agentsclimarketplace

Monocloud auth react

Skill monocloud/agent-skills/plugins/monocloud/skills/monocloud-auth-react

Official MonoCloud Agent Skills repository.

Install
npx -y skills add monocloud/agent-skills --skill monocloud-auth-react

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when integrating MonoCloud authentication into a React single-page application — installing or configuring `@monocloud/auth-react`, wrapping the tree in `<MonoCloudAuthProvider>` with `tenantDomain` / `clientId` / `appUrl`, reading auth state with `useAuth()` (`isLoading`, `isAuthenticated`, `user`, `session`) and calling its actions (`signIn`, `signOut`, `signInSilent`, `refreshSession`, `refetchUserInfo`, `getTokens`), rendering `<SignIn>` / `<SignUp>` / `<SignOut>` buttons (with `audience` / `idTokenHint` auth params) or `<Protected groups=…>` gates, mounting `<ProcessCallback>` on a dedicated callback route with `autoProcessCallback={false}`, accessing the underlying `MonoCloudWebJSClient` with `useClient()`, integrating with React Router via `postCallback`, or troubleshooting "useAuth used outside provider", StrictMode double-callbacks, popup-blocker / iframe issues, or `login_required` from silent sign-in.

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

26.1 KB, ~5.8k tokens by cl100k_base, as published. Nobody here has run it

MonoCloud React SDK (@monocloud/auth-react)

Authentication SDK for React single-page applications. Provides a context provider (<MonoCloudAuthProvider>), hooks (useAuth, useClient), and components (<SignIn>, <SignUp>, <SignOut>, <Protected>, <ProcessCallback>) wrapped around the browser implementation from @monocloud/auth-web-js.

Package identity — read this first

Use: @monocloud/auth-react (this skill). The provider is <MonoCloudAuthProvider> and the hook is useAuth.

This is not the same SDK as:

  • @monocloud/auth-web-js — the underlying browser SDK this package wraps (skill: monocloud-web-js). Use it directly for non-React SPAs.
  • @monocloud/auth-nextjs — Next.js SDK with cookie-based server sessions, middleware, route protection (skill: monocloud-auth-nextjs). Has its own useAuth hook from @monocloud/auth-nextjs/clientdon't mix the two; one or the other.
  • @monocloud/backend-node — server-side API token validation (skills: monocloud-auth-express, monocloud-auth-fastify).
  • @monocloud/management — server-only Management API client (skill: monocloud-management-js).

Pick this SDK for React SPAs built with Vite / Create React App / a custom React setup that has no SSR/server framework. If the app is Next.js, use @monocloud/auth-nextjs instead — it gives you cookie sessions, middleware, and server helpers this SDK doesn't have.

Installation

npm install @monocloud/auth-react

Peer deps: react ^18.0.0 || ^19.2.3, react-dom ^18.3.1 || ^19.2.3. Engines: Node >=16.

No environment variables — all configuration is passed as props to <MonoCloudAuthProvider>, which forwards them to the underlying MonoCloudWebJSClient.

Prerequisites (in the MonoCloud dashboard)

Configure the client as a Single Page Application with:

  • Allowed Callback URLs: the full URL the OP should redirect back to. If you use autoProcessCallback (default) this is typically just the app root (e.g. http://localhost:5173). If you mount <ProcessCallback> on a dedicated route, register appUrl + callbackPath (e.g. http://localhost:5173/callback).
  • Allowed Sign-out URLs: matches appUrl + signOutPath (or the app root if you didn't set one).
  • Allowed Origins (CORS): the bare origin of the app (e.g. http://localhost:5173).
  • Scopes: at minimum openid, profile, email. Add offline_access to get refresh tokens.

SPAs are public clients — never ship a clientSecret prop in production. The option exists on the underlying client only for advanced confidential-client setups.

Quick start

// src/main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { MonoCloudAuthProvider } from '@monocloud/auth-react';
import { App } from './App';

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <MonoCloudAuthProvider
      tenantDomain="https://<your-tenant>.us.monocloud.com"
      clientId="<your-client-id>"
      defaultAuthParams={{ scopes: 'openid profile email offline_access' }}
    >
      <App />
    </MonoCloudAuthProvider>
  </StrictMode>,
);
// src/App.tsx
import { SignIn, SignOut, Protected, useAuth } from '@monocloud/auth-react';

export function App() {
  const { isLoading, isAuthenticated, user } = useAuth();
  if (isLoading) return <p>Loading…</p>;
  return (
    <>
      {!isAuthenticated ? <SignIn>Sign In</SignIn> : <SignOut>Sign Out</SignOut>}
      <Protected fallback={<p>Sign in to view.</p>}>
        <p>Hi {user?.email}</p>
      </Protected>
    </>
  );
}

By default the provider mounts, the SDK runs processCallback() once, and the auth state lights up automatically when the user returns from the OP.

Surface at a glance

ExportKindPurpose
<MonoCloudAuthProvider>ComponentBoots a single MonoCloudWebJSClient and exposes state + actions via context.
useAuth()HookReads the auth state (isLoading, isAuthenticated, user, session, error) and exposes actions (signIn, signOut, signInSilent, refreshSession, refetchUserInfo, getTokens).
useClient()HookReturns the underlying MonoCloudWebJSClient for low-level operations (e.g. client.oidcClient.revokeToken).
<SignIn> / <SignUp>ComponentRenders a <button> that calls signIn() (with signUp: true for <SignUp>).
<SignOut>ComponentRenders a <button> that calls signOut().
<Protected>ComponentClient-side conditional render based on auth + optional group membership.
<ProcessCallback>ComponentFor dedicated callback routes. Use with autoProcessCallback={false} on the provider.
Re-exported from auth-web-jsMonoCloudWebJSClient, LocalStorage, MemoryStorage, SessionStorage, all errors, all types.

Everything in @monocloud/auth-react is client-only (every file starts with 'use client';). Don't import from this package in a Server Component / RSC.

<MonoCloudAuthProvider> — provider props

MonoCloudAuthProviderProps extends MonoCloudWebJSClientOptions (from @monocloud/auth-web-js), so every option the underlying client accepts can be passed as a prop.

Required:

PropPurpose
tenantDomainYour MonoCloud tenant URL, e.g. https://acme.us.monocloud.com.
clientIdOIDC client id (SPA client registered in the dashboard).
childrenThe subtree that should see the auth context.

Common optional:

PropDefaultPurpose
appUrlwindow.location.origin (recommended to pass explicitly)Used to build redirect URIs and validate cross-origin postMessages.
callbackPath/Relative path where MonoCloud redirects after sign-in. Must be in Allowed Callback URLs.
signOutPath/Relative path where MonoCloud redirects after sign-out. Must be in Allowed Sign-out URLs.
autoProcessCallbacktrueWhen true, the provider runs processCallback() once on mount. Set to false to handle the callback on a dedicated route with <ProcessCallback>.
defaultAuthParamsPre-set scopes / resource / responseType / prompt, etc., on every auth request.
resourcesAdditional Indicator[] for getTokens().
storagenew LocalStorage()Session persistence: LocalStorage, SessionStorage, MemoryStorage, or your own IStorage.
postCallbackfull-page reload to returnUrlHook to integrate with a client-side router (React Router, TanStack Router, etc.) instead of a hard navigation.
onSessionCreatingAsync hook to mutate the session as it is being created.
federatedSignOuttrueWhen false, signOut() only clears the local session without sending the user to MonoCloud.
fetchUserinfotrueWhen false, skip the UserInfo call after authentication.
validateIdTokentrueWhen false, skip ID token signature/claims validation. Not recommended.
authWindowTimeout600 (sec)Timeout for popup / iframe auth windows.
popupWindowWidth / popupWindowHeight375 / 600Popup dimensions.
clockSkew / clockTolerance0 / 60 (sec)ID token clock skew / tolerance.

<MonoCloudAuthProvider> constructs the client once in useState(() => new MonoCloudWebJSClient(props)) — props changes after the initial render do not rebuild the client. Treat all client-config props as bootstrap-time only. If you genuinely need to swap configuration at runtime, unmount and remount the provider (e.g. by key).

useAuth() — state + actions

'use client';
import { useAuth } from '@monocloud/auth-react';

export function Profile() {
  const {
    isLoading, isAuthenticated, user, session, error,
    signIn, signOut, signInSilent, refreshSession, refetchUserInfo, getTokens,
  } = useAuth();

  if (isLoading) return <p>Loading…</p>;
  if (error)     return <p>Error: {error.message}</p>;
  if (!isAuthenticated) return <button onClick={() => signIn()}>Sign in</button>;

  return (
    <>
      <p>Hi {user?.email}</p>
      <button onClick={() => signOut()}>Sign out</button>
    </>
  );
}

State shape (AuthStateMonoCloudAuth):

FieldTypeNotes
isLoadingbooleantrue during bootstrap (processCallback + initial getSession) and during any in-flight signIn/signOut.
isAuthenticatedbooleantrue when a session exists.
userMonoCloudUser | undefinedID-token claims + UserInfo claims (filtered).
sessionMonoCloudSession | undefinedIncludes idToken, accessTokens[], refreshToken, authorizedScopes.
errorError | undefinedLast error from a signIn, signOut, or initial processCallback.

Action methods proxy to the underlying client; all of them re-sync the auth state on success (i.e., the next useAuth() read reflects the new session). They are stable across renders (memoized with useCallback).

signIn() and signOut() do not re-throw caught errors — they put the error on state.error and resolve. If you need imperative throw-on-failure semantics, use useClient() and call the client directly.

Calling a hook outside the provider throws MonoCloudJsError: useAuth() can only be used inside a <MonoCloudAuthProvider>....

useClient() — escape hatch

For anything useAuth() does not cover — usually OIDC-level operations like token revocation, decoding, JWKS, or client.oidcClient.* calls — read the underlying MonoCloudWebJSClient:

'use client';
import { useAuth, useClient } from '@monocloud/auth-react';

export function RevokeButton() {
  const { getTokens } = useAuth();
  const client = useClient();

  const revoke = async () => {
    const tokens = await getTokens();
    await client.oidcClient.revokeToken(tokens.accessToken);
  };

  return <button onClick={revoke}>Revoke access token</button>;
}

useClient() returns the same MonoCloudWebJSClient instance the provider built; calling its methods directly bypasses the state sync that the useAuth() actions do. If you mutate the session via the raw client (e.g. you call client.signOut() instead of the hook's signOut), call any of the useAuth actions afterwards to re-sync (or simpler: just use the hook).

Components

<SignIn> / <SignUp>

Render a <button> (forwards every HTMLButtonElement prop). When clicked it calls signIn() (with signUp: true for <SignUp>).

import { SignIn, SignUp, SignOut } from '@monocloud/auth-react';

<SignIn>Sign In</SignIn>
<SignIn mode="popup" loginHint="[email protected]">Sign in (popup)</SignIn>
<SignIn authenticatorHint="google" className="btn btn-primary">Continue with Google</SignIn>
<SignIn returnUrl="/dashboard">Sign in & go to dashboard</SignIn>
<SignIn audience="https://api.example.com">Sign in (audience-scoped token)</SignIn>
<SignIn idTokenHint={idToken} prompt="none">Silent re-auth</SignIn>
<SignUp returnUrl="/welcome">Create account</SignUp>

<SignIn> accepts everything SignInOptions accepts (except signUp) plus button props. <SignUp> accepts the same minus signUp, authenticatorHint, loginHint, prompt (those are sign-in-only).

<SignOut>

<SignOut>Sign Out</SignOut>
<SignOut mode="popup">Sign out (popup)</SignOut>
<SignOut federatedSignOut={false}>Local sign out only</SignOut>
<SignOut postLogoutRedirectUri="https://example.com/bye">Sign out and leave</SignOut>
<SignOut idTokenHint={idToken}>Sign out with explicit id_token_hint</SignOut>

Accepts every SignOutOptions field plus button props.

The render is a plain <button>. If you need an <a> or a custom element, ignore the components and call signIn() / signOut() from useAuth() directly in your own component.

<Protected> — client-side gate with optional groups

import { Protected } from '@monocloud/auth-react';

// auth-only
<Protected fallback={<p>Sign in to view.</p>}>
  <SecretContent />
</Protected>

// require ANY of these groups
<Protected
  groups={['admin']}
  onGroupAccessDenied={user => <p>Not authorized: {user.email}</p>}
>
  <AdminPanel />
</Protected>

// require ALL of these groups
<Protected
  groups={['admin', 'billing']}
  matchAllGroups
  onGroupAccessDenied={user => <p>Need both admin AND billing.</p>}
>
  <SensitiveSettings />
</Protected>

// custom claim name (default is "groups")
<Protected groups={['admin']} groupsClaim="roles">
  <AdminPanel />
</Protected>

Behavior matrix:

StateRenders
isLoadingnull
Error / unauthenticated / no userfallback (or null if no fallback)
Authenticated, no groups propchildren
Authenticated, in required groupschildren
Authenticated, not in required groupsonGroupAccessDenied(user) (default: <></>)

<Protected> only affects what is rendered. The component tree (children) is still in the bundle, and any data those components fetch will still hit the API. Enforce authorization on the API side as well (see monocloud-auth-express / monocloud-auth-fastify).

<ProcessCallback> — dedicated callback route

By default, <MonoCloudAuthProvider> calls processCallback() itself on mount (the autoProcessCallback prop defaults to true) — there is no need for a separate callback route in most apps.

If you do want one (e.g. an isolated /callback page that shows a "Completing sign in…" UI), set autoProcessCallback={false} on the provider and render <ProcessCallback> on that route:

// main.tsx
<MonoCloudAuthProvider
  tenantDomain="https://<your-tenant>"
  clientId="<your-client-id>"
  callbackPath="/callback"
  autoProcessCallback={false}
>
  <RouterProvider router={router} />
</MonoCloudAuthProvider>

// pages/Callback.tsx
import { ProcessCallback } from '@monocloud/auth-react';

export default function Callback() {
  return (
    <ProcessCallback
      loading={<p>Completing sign in…</p>}
      error={err => <p>Sign in failed: {err.message}</p>}
    >
      <p>Done — redirecting…</p>
    </ProcessCallback>
  );
}

Pick one path — auto vs dedicated. Mounting <ProcessCallback> without setting autoProcessCallback={false} is wasteful (the provider also runs it) and can produce a brief duplicate-processing state.

Where the user lands after a successful callback is controlled by the provider-level postCallback prop, not by <ProcessCallback>. See "Integrating with a client-side router" below.

Integrating with a client-side router (React Router / TanStack Router)

The default postCallback performs a full page reload to returnUrl (set via signIn({ returnUrl })). That wipes Redux/Zustand/Jotai state and breaks MemoryStorage. With a client-side router, pass a postCallback:

'use client';
import { MonoCloudAuthProvider } from '@monocloud/auth-react';
import { useNavigate } from 'react-router-dom';

export function AuthShell({ children }: { children: React.ReactNode }) {
  const navigate = useNavigate();

  return (
    <MonoCloudAuthProvider
      tenantDomain="https://<your-tenant>"
      clientId="<your-client-id>"
      postCallback={state => navigate(state.returnUrl ?? '/')}
    >
      {children}
    </MonoCloudAuthProvider>
  );
}

For routers whose navigation hook is only available inside the <Router> subtree (the common case), place <MonoCloudAuthProvider> inside the router, not above it:

<BrowserRouter>
  <AuthShell>{/* routes */}</AuthShell>
</BrowserRouter>

postCallback runs after both sign-in and sign-out callbacks. state.signOut tells you which.

Access tokens for API calls

'use client';
import { useAuth } from '@monocloud/auth-react';

export function FetchProtected() {
  const { getTokens } = useAuth();

  const handleClick = async () => {
    const { accessToken } = await getTokens();
    const res = await fetch('/api/things', {
      headers: { Authorization: `Bearer ${accessToken}` },
    });
    /* ... */
  };

  return <button onClick={handleClick}>Load things</button>;
}

getTokens() transparently refreshes near-expired tokens via the Refresh Token Grant. It requires offline_access to be in the granted scopes at sign-in time — otherwise no refresh token is issued and the auto-refresh path throws MonoCloudValidationError. Set it on the provider:

<MonoCloudAuthProvider
  /* ... */
  defaultAuthParams={{ scopes: 'openid profile email offline_access' }}
>

For audience-specific tokens, pre-register the resource and request via getTokens:

<MonoCloudAuthProvider
  /* ... */
  resources={[{ resource: 'https://api.example.com', scopes: 'read:data write:data' }]}
>

// ...

const { accessToken } = await getTokens({ resource: 'https://api.example.com' });

Errors

All errors extend MonoCloudAuthBaseError (which extends Error). They are re-exported from @monocloud/auth-web-js. Use instanceof to branch; there is no statusCode field.

ClassThrown for
MonoCloudOPErrorOAuth/OIDC error from the authorization server. Exposes .error and .errorDescription. Most common in this SDK: login_required from signInSilent, access_denied from a cancelled sign-in.
MonoCloudValidationErrorBad state — no session, missing refresh token, scopes/responseType mismatch.
MonoCloudTokenErrorToken operation failed (e.g. ID token validation).
MonoCloudHttpErrorNetwork / unexpected HTTP response talking to MonoCloud.
MonoCloudJsErrorBrowser-environment failure (popup blocked, iframe in cross-origin-isolated context, hooks called outside provider, redirect attempted from inside an iframe, etc.).
MonoCloudAuthBaseErrorBase class — catch this when you want to handle any SDK error generically.

For signIn / signOut (the hook actions), errors are surfaced on state.error rather than thrown. For signInSilent / refreshSession / refetchUserInfo / getTokens (and any direct useClient() calls), errors are thrown as usual:

import { MonoCloudOPError } from '@monocloud/auth-react';

const { signInSilent } = useAuth();

useEffect(() => {
  signInSilent().catch(e => {
    if (e instanceof MonoCloudOPError && e.error === 'login_required') return;
    console.error(e);
  });
}, [signInSilent]);

Common pitfalls

  1. Using useAuth() or useClient() outside the provider. Throws MonoCloudJsError: useAuth() can only be used inside a <MonoCloudAuthProvider>.... Make sure the provider is an ancestor of every component that calls a hook.
  2. Trying to reconfigure the provider by changing props. The underlying MonoCloudWebJSClient is created once (on the provider's first render). Prop changes are ignored. To swap config, remount the provider with a new key.
  3. Mounting <ProcessCallback> without autoProcessCallback={false}. Both code paths run processCallback() — the second one is a no-op but adds an unnecessary loading flicker. Pick one.
  4. Using this skill in a Next.js app. Don't. Use @monocloud/auth-nextjs instead — it gives cookie sessions, middleware, and server helpers. This SDK is for plain React SPAs.
  5. Forgetting offline_access. Refresh tokens are only issued when offline_access is granted. Without it refreshSession() and the auto-refresh in getTokens() throw MonoCloudValidationError. Add it to defaultAuthParams.scopes (or pass via <SignIn scopes="…">).
  6. signIn({ mode: 'popup' }) from useEffect. Browsers block popups not opened from a user gesture. Call inside a click handler — the <SignIn> component already does this correctly; if you call signIn yourself, do it from onClick, not useEffect.
  7. Mismatched dashboard URLs. appUrl + callbackPath (and appUrl + signOutPath) must exactly match the dashboard entries — including scheme, host, port, path. Same for the CORS origin.
  8. MemoryStorage + default postCallback. The default postCallback does a full page reload, which empties memory and drops the just-created session. Either keep the default LocalStorage/SessionStorage or pass a postCallback that navigates with your router (no reload).
  9. Wrapping the provider above <BrowserRouter> when postCallback uses useNavigate. useNavigate only works inside <BrowserRouter>. Put the provider inside the router subtree.
  10. Shipping a clientSecret prop. SPAs are public clients. Don't pass clientSecret — the bundle is public and the secret leaks.
  11. Calling client.signOut() from useClient() and expecting isAuthenticated to flip. The raw client does not re-sync the context — use the hook's signOut, or call any other useAuth action afterwards to re-sync.
  12. Treating <Protected> as a security boundary. It only gates what is rendered. The children code is still in the bundle, and anything they fetch still hits the API. Enforce on the server.

Onboarding checklist for a fresh integration

  1. npm install @monocloud/auth-react.
  2. In the MonoCloud dashboard, configure the client as a Single Page Application and register the Callback URL, Sign-out URL, and Allowed Origin matching the dev origin (e.g. http://localhost:5173). Enable Allow Access Tokens via the Browser and Allow Offline Access if you need refresh tokens.
  3. Wrap the root render in <MonoCloudAuthProvider tenantDomain={…} clientId={…} defaultAuthParams={{ scopes: 'openid profile email offline_access' }}>.
  4. Read auth state with useAuth(); gate UI with <Protected fallback={…}>; add <SignIn> / <SignOut> (or <SignUp>) buttons where needed.
  5. For protected fetches, call getTokens() from useAuth() and send accessToken in the Authorization header.
  6. (Optional) For a dedicated callback route, set autoProcessCallback={false} and render <ProcessCallback> on that route.
  7. (Optional) For client-side-router navigation after callbacks, pass postCallback={state => navigate(state.returnUrl ?? '/')}.
  8. Run node skills/monocloud-auth-react/scripts/verify.js to sanity-check dependency wiring and provider/hook usage.

Deeper reference

  • references/api-surface.md — every export, full provider prop shape, hook return type, component prop shapes, error classes.
  • references/troubleshooting.md — extended symptom → cause → fix index covering StrictMode double-callbacks, "useAuth outside provider," popup blockers, iframe / cross-origin issues, refresh-token gotchas, hooks-outside-router pitfalls, and training-data SDK ghosts.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.