Skip to content

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

Wrap your AppShell with the authentication provider:

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

const App = () => (
  <AuthProvider
    apiEndpoint={TAILOR_PLATFORM_URL}
    clientId={CLIENT_ID}
    redirectUri={REDIRECT_URI}
    autoLogin={true}
    guardComponent={() => <LoadingScreen />}
  >
    <AppShell {...appShellConfig}>
      <SidebarLayout />
    </AppShell>
  </AuthProvider>
);

Find the above values in Tailor Console:

  • Tailor Platform URL: 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: Authentication client identifier

    • Found in Application > Auth screen in your Tailor Platform console
  • Redirect URI: OAuth2 callback URL (optional)

    • Defaults to window.location.origin if not provided
    • Must match the redirect URI configured in your Tailor Platform Auth settings

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

See the API for more details.

Authentication Hook

Use the useAuth hook to access authentication state and methods:

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

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

  if (authState.isLoading) {
    return <div>Loading...</div>;
  }

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

  return (
    <div>
      <p>Welcome, {authState.user.name || authState.user.email}!</p>
      <p>User ID: {authState.user.id}</p>
      <button onClick={logout}>Sign Out</button>
    </div>
  );
};

Authentication State

The authState object contains:

PropertyTypeDescription
isLoadingbooleanWhether auth status is being checked
isAuthenticatedbooleanWhether user is authenticated
userUser | nullCurrent user object (null if not authenticated)

See the API for more details.

Extending User Type

By default, the user object has these fields:

  • id: string
  • email: string
  • name?: string

If your application needs additional user fields (e.g., roles, organization info), you can extend the user type using TypeScript module augmentation:

Step 1: Define Custom User Type

tsx
// types/auth.d.ts (or any .ts/.tsx file in your project)
declare module "@tailor-platform/app-shell" {
  interface AuthRegister {
    user: DefaultUser & {
      roles: Array<string>;
      organizationId: string;
      // Add any other custom fields your API returns
    };
  }
}

Step 2: Provide Matching meQuery

The meQuery prop defines the GraphQL query used to fetch the authenticated user. The fields must match your custom user type:

tsx
<AuthProvider
  apiEndpoint="https://xyz.erp.dev"
  clientId="your-client-id"
  meQuery={`
    query {
      me {
        id
        email
        name
        roles
        organizationId
      }
    }
  `}
>
  <AppShell {...config}>
    <SidebarLayout />
  </AppShell>
</AuthProvider>

Step 3: Access Typed User Data

After the above setup, authState.user will be fully typed:

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

const MyComponent = () => {
  const { authState } = useAuth();

  // TypeScript knows these properties exist
  console.log(authState.user.roles); // Array<string>
  console.log(authState.user.organizationId); // string
  console.log(authState.user.email); // string (from DefaultUser)

  return <div>...</div>;
};

OAuth Callback Handling

If your authentication flow requires a dedicated callback page, use the handleCallback method:

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

const CallbackPage = () => {
  const { handleCallback } = useAuth();

  useEffect(() => {
    handleCallback()
      .then(() => {
        // Redirect to home or intended page
        window.location.href = "/";
      })
      .catch((error) => {
        console.error("Auth callback failed:", error);
      });
  }, [handleCallback]);

  return <div>Processing authentication...</div>;
};

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.

tsx
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:

tsx
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>
  );
}

AuthClientConfig

PropertyTypeRequiredDescription
clientIdstringYesOAuth2 client ID from Tailor Platform console
appUristringYesYour Tailor Platform application URL
redirectUristringNoOAuth2 redirect URI (defaults to window.location.origin)

EnhancedAuthClient Methods

Method / PropertyTypeDescription
getAppUri()() => stringReturns the appUri used to create this client
fetchtypeof fetchAuthenticated fetch with built-in DPoP proof generation and token refresh

See the API for more details.

Integration with AppShell

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

  • OAuth2 token management
  • GraphQL request authentication
  • Session persistence and token refresh
  • Automatic redirects for protected routes

Simply wrap your AppShell with the provider and authentication will be handled automatically throughout your application.