Skip to content

Latest commit

 

History

History
229 lines (173 loc) · 7.87 KB

File metadata and controls

229 lines (173 loc) · 7.87 KB
title Authentication
description Set up OAuth2/OIDC authentication with Tailor Platform's Auth service using the AuthProvider component

Authentication

AppShell provides built-in OAuth2/OIDC authentication through the AuthProvider component, which integrates seamlessly with Tailor Platform's Auth service. The provider supports any IdP configured in your Tailor Platform application (built-in IdP, Google, Okta, Auth0, etc.).

Quick Start

First, create an auth client, then wrap your app with AuthProvider:

import {
  createAuthClient,
  AuthProvider,
  AppShell,
  SidebarLayout,
} from "@tailor-platform/app-shell";

const authClient = createAuthClient({
  clientId: CLIENT_ID,
  appUri: TAILOR_PLATFORM_URL,
});

const App = () => (
  <AuthProvider client={authClient} autoLogin={true} guardComponent={() => <LoadingScreen />}>
    <AppShell modules={modules}>
      <SidebarLayout />
    </AppShell>
  </AuthProvider>
);

Find the above values in Tailor Console:

  • Tailor Platform URL (appUri): Your application's base URL

    • Obtained from the Application Overview screen in Tailor Platform
    • Use the domain portion of the 'Accessing the API endpoint of this application' setting
    • Example: "https://xyz.erp.dev" (no /query suffix needed)
  • Client ID (clientId): Authentication client identifier

    • Found in Application > Auth screen in your Tailor Platform console

The above code will:

  • Automatically redirect unauthenticated users to the login page (if autoLogin is true)
  • Show the guardComponent while loading or when unauthenticated
  • Handle token management and session persistence automatically

Authentication Hook

Use the useAuth hook to access authentication state and methods:

import { useAuth } from "@tailor-platform/app-shell";

const UserProfile = () => {
  const { isReady, isAuthenticated, login, logout } = useAuth();

  if (!isReady) {
    return <div>Loading...</div>;
  }

  if (!isAuthenticated) {
    return <button onClick={login}>Sign In</button>;
  }

  return <button onClick={logout}>Sign Out</button>;
};

Return Value

Property Type Description
isAuthenticated boolean Whether the user is currently authenticated
isReady boolean Whether the initial authentication check has completed
error string | null Error message if authentication failed
login () => Promise<void> Initiates the login/redirect flow
logout () => Promise<void> Clears tokens and ends the session
checkAuthStatus () => Promise<AuthState> Re-checks auth status (always makes a network request)

Suspense-Compatible Hook

Use useAuthSuspense when you want React Suspense to handle the loading state:

import { Suspense } from "react";
import { useAuthSuspense } from "@tailor-platform/app-shell";

function App() {
  return (
    <AuthProvider client={authClient}>
      <Suspense fallback={<div>Loading authentication...</div>}>
        <ProtectedContent />
      </Suspense>
    </AuthProvider>
  );
}

function ProtectedContent() {
  // isReady is guaranteed to be true here — Suspense handles the loading state
  const { isAuthenticated, login, logout } = useAuthSuspense();

  if (!isAuthenticated) {
    return <button onClick={login}>Log In</button>;
  }

  return <button onClick={logout}>Log Out</button>;
}

Auth Client

Use createAuthClient to create an authentication client that you pass to AuthProvider. The client handles token management and provides an authenticated fetch method for use with GraphQL clients.

import { createAuthClient } from "@tailor-platform/app-shell";

const authClient = createAuthClient({
  clientId: "your-client-id",
  appUri: "https://xyz.erp.dev",
});

Using authClient.fetch with a GraphQL Client

Pass authClient.fetch directly to your GraphQL client (e.g., urql). It transparently handles DPoP proof generation and token refresh on every request:

import { createAuthClient, AuthProvider } from "@tailor-platform/app-shell";
import { createClient, Provider } from "urql";

const authClient = createAuthClient({
  clientId: "your-client-id",
  appUri: "https://xyz.erp.dev",
});

const urqlClient = createClient({
  url: `${authClient.getAppUri()}/query`,
  fetch: authClient.fetch,
});

function App() {
  return (
    <AuthProvider client={authClient} autoLogin={true}>
      <Provider value={urqlClient}>
        <YourAppComponents />
      </Provider>
    </AuthProvider>
  );
}

Using createAIGatewayClient with AI Gateway

createAIGatewayClient reuses the same authenticated fetch path as the rest of AppShell. Requests go through authClient.fetch, so DPoP proof generation and token refresh stay in the auth layer.

import { createAuthClient, createAIGatewayClient, useAIChat } from "@tailor-platform/app-shell";

const authClient = createAuthClient({
  clientId: "your-client-id",
  appUri: "https://xyz.erp.dev",
});

const aiClient = createAIGatewayClient({
  gatewayUri: "https://your-ai-gateway.example.com",
  authClient,
});

function ChatScreen() {
  const { messages, sendMessage, status, stop } = useAIChat({
    client: aiClient,
    model: "gpt-5-mini",
  });

  return (
    <div>
      {messages.map((message) => (
        <div key={message.id}>
          {message.role}: {message.content}
        </div>
      ))}

      <button onClick={() => void sendMessage("Hello")}>Send</button>
      <button onClick={stop} disabled={status !== "submitted" && status !== "streaming"}>
        Stop
      </button>
    </div>
  );
}

AuthClientConfig

Property Type Required Description
clientId string Yes OAuth2 client ID from Tailor Platform console
appUri string Yes Your Tailor Platform application URL
redirectUri string No OAuth2 redirect URI (defaults to window.location.origin)

EnhancedAuthClient Methods

Method / Property Type Description
getAppUri() () => string Returns the appUri used to create this client
fetch typeof fetch Authenticated fetch with built-in DPoP proof generation and token refresh

AuthProvider Props

Prop Type Required Description
client EnhancedAuthClient Yes Auth client created with createAuthClient
autoLogin boolean No Automatically redirect unauthenticated users to login
guardComponent () => React.ReactNode No Rendered while loading or when not authenticated

Integration with AppShell

The authentication provider works seamlessly with AppShell's data layer, automatically handling:

  • OAuth2 token management
  • Authenticated fetch with DPoP proof generation
  • Session persistence and token refresh
  • Automatic redirects for protected routes (via autoLogin)

OAuth callback parameters (code, state) are automatically cleaned from the URL after a successful login — no dedicated callback page is needed.