### Install jose library for Shoo token verification Source: https://docs.shoo.dev/docs/server-verification This command installs the 'jose' library, which is required for verifying Shoo id_tokens on your server. Ensure you have Bun installed to run this command. ```bash bun add jose ``` -------------------------------- ### Install Shoo React Package using Bun Source: https://docs.shoo.dev/docs/index This command installs the Shoo React package, which provides a React hook and a Convex adapter for integrating Google sign-in into React applications. It uses the Bun package manager. ```bash bun add @shoojs/react ``` -------------------------------- ### Install @shoojs/auth with Bun Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Installs the @shoojs/auth package using the Bun package manager. This is the primary method for adding the library to your project. ```bash bun add @shoojs/auth ``` -------------------------------- ### ShooAuth Installation and Usage Source: https://docs.shoo.dev/docs/api-reference/shoo-react Provides instructions on how to install and use the `useShooAuth` hook, including its options and return values. ```APIDOC ## ShooAuth ### Description Installs and configures the Shoo authentication hook. ### Method `useShooAuth(options)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **options** (object) - Optional - Configuration options for ShooAuth. * **redirectUri** (string) - The URI to redirect to after authentication. * **clientId** (string) - The client ID for Shoo authentication. ### Return Value * **authStatus** (string) - The current authentication status ('loading', 'authenticated', 'unauthenticated'). * **login** (function) - Function to initiate the login process. * **logout** (function) - Function to initiate the logout process. ### Behavior Handles the authentication flow using Shoo's authentication service. ### Example ```javascript import { useShooAuth } from 'shoo-auth'; const { authStatus, login, logout } = useShooAuth({ redirectUri: 'http://localhost:3000/callback', clientId: 'your-client-id' }); if (authStatus === 'loading') { return

Loading...

; } if (authStatus === 'authenticated') { return ; } return ; ``` ``` -------------------------------- ### Start Sign-In Flow Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Initiates the Shoo authentication sign-in process. This method generates a PKCE bundle, stores it, and redirects the user to the Shoo authorization endpoint. It can optionally accept parameters to override default PII settings, specify a return URL, or customize redirect/client details. ```javascript await auth.startSignIn(); // With options await auth.startSignIn({ requestPii: true, returnTo: "/dashboard", }); ``` -------------------------------- ### Example: Shoo Authentication Profile Component Source: https://docs.shoo.dev/docs/api-reference/shoo-react An example React component demonstrating how to use the `useShooAuth` hook to display user profile information and handle sign-in/sign-out actions. It conditionally renders UI based on the authentication state. ```jsx import { useShooAuth } from "@shoojs/react"; export function Profile() { const { identity, claims, loading, signIn, clearIdentity } = useShooAuth(); if (loading) return

Loading…

; if (!identity.userId) { return (
); } return (

ID: {identity.userId}

{claims?.email &&

Email: {claims.email}

} {claims?.name &&

Name: {claims.name}

}
); } ``` -------------------------------- ### ShooAuthClient Methods Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Provides methods for managing the authentication flow, including starting sign-in, handling callbacks, and retrieving user identity. ```APIDOC ## ShooAuthClient ### client.startSignIn(params?) #### Description Generates a PKCE bundle, stores the verifier in `sessionStorage`, and redirects the browser to the Shoo authorize endpoint. #### Method `startSignIn` #### Parameters ##### StartSignInOptions - **requestPii** (boolean) - Optional - Override default PII setting. - **returnTo** (string) - Optional - URL to redirect to after sign-in. - **redirectUri** (string) - Optional - Override callback URL. - **clientId** (string) - Optional - Override client ID. - **shooBaseUrl** (string) - Optional - Override Shoo server URL. #### Returns `Promise<{ url: string; bundle: PkceBundle }>` #### Request Example ```javascript // Basic usage await auth.startSignIn(); // With options await auth.startSignIn({ requestPii: true, returnTo: "/dashboard", }); ``` --- ### client.handleCallback(params?) #### Description The high-level callback handler. Exchanges the authorization code, persists identity, and redirects to the stored return-to URL. Use this in your callback page. #### Method `handleCallback` #### Parameters ##### HandleCallbackOptions - **url** (string) - Optional - URL to parse. Defaults to `window.location.href`. - **redirectTo** (string) - Optional - Explicit redirect target (overrides stored return-to). - **returnTo** (string) - Optional - Alias for `redirectTo`. - **fallbackPath** (string) - Optional - Fallback if no return-to is stored. #### Returns `Promise` - Returns `null` if no callback params are present. #### Request Example ```javascript // In your callback page try { const token = await auth.handleCallback(); // Browser redirects automatically after this call } catch (error) { console.error("Authentication callback failed:", error); } ``` --- ### client.finishSignIn(params?) #### Description Lower-level code exchange. Unlike `handleCallback`, this does not automatically redirect. Use this when you need more control. #### Method `finishSignIn` #### Parameters ##### FinishSignInOptions - **url** (string) - Optional - URL to parse. Defaults to `window.location.href`. - **clearCallbackParams** (boolean) - Optional - Remove code/state from URL bar. Defaults to `true`. - **redirectAfter** (boolean) - Optional - Redirect to return-to URL. Defaults to `false`. - **consumeReturnTo** (boolean) - Optional - Remove stored return-to after reading. Defaults to `true`. - **redirectTo** (string) - Optional - Explicit redirect target. - **returnTo** (string) - Optional - Alias for `redirectTo`. - **fallbackPath** (string) - Optional - Fallback path. Defaults to `/`. - **redirectUri** (string) - Optional - Override callback URL. - **clientId** (string) - Optional - Override client ID. - **shooBaseUrl** (string) - Optional - Override Shoo server URL. #### Returns `Promise` #### Request Example ```javascript // Example: Exchange code without automatic redirect const token = await auth.finishSignIn({ redirectAfter: false, }); if (token) { console.log("Sign-in finished successfully."); // Proceed with application logic } else { console.log("No token received."); } ``` --- ### client.getIdentity(storageKey?) #### Description Reads the persisted identity from `localStorage`. #### Method `getIdentity` #### Parameters - **storageKey** (string) - Optional - The `localStorage` key to read identity from. Defaults to the key provided during `createShooAuth`. #### Returns `ShooIdentity` object or `null` if no identity is found. **ShooIdentity Properties:** - **userId** (string | null) - The user's domain-scoped ID, or `null` if signed out. - **token** (string | undefined) - The raw `id_token` JWT. - **expiresIn** (number | undefined) - Token lifetime in seconds. - **receivedAt** (number | undefined) - Timestamp when the token was stored. #### Request Example ```javascript const identity = auth.getIdentity(); if (identity && identity.userId) { console.log("User ID:", identity.userId); console.log("Token expires in:", identity.expiresIn, "seconds"); } else { console.log("User is not signed in."); } ``` --- ### client.persistIdentity(userId, token, storageKey?, extras?) #### Description Writes identity to `localStorage`. Called automatically by `handleCallback` and `finishSignIn`. #### Method `persistIdentity` #### Parameters - **userId** (string) - The user's domain-scoped ID. - **token** (string) - The raw `id_token` JWT. - **storageKey** (string) - Optional - The `localStorage` key to store identity under. - **extras** (object) - Optional - Additional properties to store with the identity (e.g., `expiresIn`, `receivedAt`). #### Request Example ```javascript // Typically called internally by the library, but can be used manually if needed await auth.persistIdentity("ps_a1B2...", "eyJ...", undefined, { expiresIn: 3600, receivedAt: Date.now() / 1000, }); ``` ``` -------------------------------- ### Get User Identity (Vanilla JS) Source: https://docs.shoo.dev/docs/getting-started-vanilla Retrieve the user's identity information, including their unique user ID and signed ID token, after successful authentication. This is typically done client-side using JavaScript. ```javascript const identity = window.Shoo.getIdentity(); console.log(identity.userId); // "ps_a1B2c3..." or null console.log(identity.token); // signed id_token JWT ``` -------------------------------- ### Get Persisted User Identity Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Retrieves the user's identity information (userId, token, expiration, etc.) that was previously persisted in `localStorage`. This method allows you to check the current sign-in status of the user. ```javascript const identity = auth.getIdentity(); // { userId: "ps_a1B2...", token: "eyJ...", expiresIn: 300, receivedAt: 1234567890 } ``` -------------------------------- ### Create Google Sign-in Link Source: https://docs.shoo.dev/docs/getting-started-vanilla Generate an anchor tag that initiates the Google sign-in process. The `redirect_uri` should point to your application's callback endpoint. ```html Sign in ``` -------------------------------- ### Create Shoo Authentication Client Instance Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Demonstrates how to create an instance of the Shoo authentication client using the `createShooAuth` function. It shows the basic usage with the required `shooBaseUrl` option. ```javascript import { createShooAuth } from "@shoojs/auth"; const auth = createShooAuth({ shooBaseUrl: "https://shoo.dev", }); ``` -------------------------------- ### Programmatic Sign-in (Vanilla JS) Source: https://docs.shoo.dev/docs/getting-started-vanilla Initiate the sign-in process programmatically using Shoo.js. Options include specifying a return URL or requesting additional profile data. ```javascript // Basic sign-in window.Shoo.startSignIn(); // With return-to URL window.Shoo.startSignIn({ returnTo: "/dashboard" }); // With profile data (email, name, picture) window.Shoo.startSignIn({ requestPii: true }); ``` -------------------------------- ### Authentication Flow Source: https://docs.shoo.dev/docs/how-it-works Details the step-by-step authentication process when a user clicks 'Sign in', involving your app, shoo.dev, and Google. ```APIDOC ## Authentication Flow This describes the sequence of events when a user initiates the sign-in process. ### Description 1. **startSignIn()**: Your app generates a PKCE bundle, stores the verifier, and redirects the user to shoo.dev's `/authorize` endpoint with `code_challenge`, `redirect_uri`, and `state`. 2. **Redirect to Google**: shoo.dev redirects the user to Google for authentication. 3. **User Authenticates**: The user authenticates with Google. 4. **Callback**: Google redirects back to shoo.dev with a `google_code`. 5. **Exchange Google Code**: shoo.dev exchanges the `google_code` for a Google identity, derives a `pairwise_sub`, and signs an `id_token` using ES256. 6. **Redirect to App**: shoo.dev redirects the user back to your app with a `code` and `state`. 7. **exchangeCode()**: Your app calls `POST /token` with the `code` and `code_verifier` to exchange it for an `id_token` and `pairwise_sub`. 8. **Verify PKCE**: Shoo verifies the PKCE code exchange. 9. **Store Identity**: Your app stores the user's identity and redirects the user to their intended destination. ### Method POST ### Endpoint `/token` ### Parameters #### Query Parameters - **code** (string) - Required - The authorization code received from shoo.dev. - **code_verifier** (string) - Required - The original PKCE code verifier generated by the client. #### Request Body None ### Request Example ``` POST /token HTTP/1.1 Host: shoo.dev Content-Type: application/x-www-form-urlencoded code=shoo_code&code_verifier=your_code_verifier ``` ### Response #### Success Response (200) - **id_token** (string) - The signed JWT ID token containing user information. - **pairwise_sub** (string) - The domain-scoped, stable user identifier. #### Response Example ```json { "id_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IjEyMzQ1In0.eyJzdWIiOiJwc19hMTJjM2Q0ZTVmNiIsImF1ZCI6Im9yaWdpbjpodHRwczovL215YXBwLmNvbSIsImlzcyI6Imh0dHBzOi8vc2hvb28uZGV2IiwiZXhwIjoxNjgwMDAwMDAwLCJpYXQiOjE2ODAwMDAwMDB9.signature", "pairwise_sub": "ps_a1B2c3D4e5F6..." } ``` ``` -------------------------------- ### Set up Shoo Auth Callback Route in Next.js Source: https://docs.shoo.dev/docs/getting-started Provides the necessary code for a callback route in a Next.js application when using Shoo authentication. This page handles the redirect after Google authentication, ensuring the SPA callback is managed correctly. Vite and other SPAs handle this automatically. ```jsx "use client"; import { useShooAuth } from "@shoojs/react"; export default function ShooCallback() { useShooAuth(); return

Signing in…

; } ``` -------------------------------- ### Include Shoo Hosted Script for Zero Dependencies Source: https://docs.shoo.dev/docs/index This HTML script tag allows you to include the Shoo JavaScript library directly into your web page. It requires no bundler and provides a zero-dependency solution for integrating Google sign-in. ```html ``` -------------------------------- ### Implement Google Sign-In in React App Source: https://docs.shoo.dev/docs/getting-started Demonstrates how to add Google sign-in functionality to a React application using the `useShooAuth` hook. It handles loading states, sign-in button display, and user sign-out. The hook manages PKCE, Google redirect, token exchange, and identity persistence. ```jsx import { useShooAuth } from "@shoojs/react"; export default function App() { const { identity, loading, signIn, clearIdentity } = useShooAuth(); if (loading) return

Loading…

; if (!identity.userId) return ; return (

Welcome, {identity.userId}

); } ``` -------------------------------- ### Generate PKCE Bundle Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Generates a Proof Key for Code Exchange (PKCE) bundle, which includes a random state, a verifier, and a S256 challenge. This is used to enhance the security of the authorization code flow. ```javascript const bundle = await auth.createPkceBundle(); // { state: "...", verifier: "...", challenge: "..." } ``` -------------------------------- ### createShooAuth Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Creates a Shoo auth client instance. This is the main entry point for using the Shoo authentication library. ```APIDOC ## createShooAuth(options) ### Description Creates a Shoo auth client instance. This is the main entry point. ### Method `createShooAuth` ### Parameters #### Options - **shooBaseUrl** (string) - Optional - Shoo server URL. Defaults to `"https://shoo.dev"`. - **callbackPath** (string) - Optional - Path Shoo redirects to after auth. Defaults to `"/auth/callback"`. - **redirectUri** (string) - Optional - Full callback URL. Auto-derived from `callbackPath`. - **clientId** (string) - Optional - Client ID. Auto-derived from redirect URI origin. Defaults to `"origin:{your_origin}"`. - **requestPii** (boolean) - Optional - Request email/name/picture by default. Defaults to `false`. - **storageKey** (string) - Optional - localStorage key for identity. Defaults to `"shoo_identity"`. - **pkceStorageKey** (string) - Optional - sessionStorage key for PKCE bundle. Defaults to `"shoo_pkce"`. - **returnToStorageKey** (string) - Optional - sessionStorage key for return URL. Defaults to `"shoo_return_to"`. - **fallbackPath** (string) - Optional - Redirect target when no return-to is stored. Defaults to `/`. ### Returns A `ShooAuthClient` instance. ### Request Example ```javascript import { createShooAuth } from "@shoojs/auth"; const auth = createShooAuth({ shooBaseUrl: "https://shoo.dev", }); ``` ``` -------------------------------- ### Shoo.dev Server Endpoints Source: https://docs.shoo.dev/docs/how-it-works This section outlines the available server endpoints for interacting with the Shoo.dev authentication service. ```APIDOC ## GET /authorize ### Description Starts the authentication flow. ### Method GET ### Endpoint /authorize ### Parameters #### Query Parameters - **client_id** (string) - Required - Your Shoo.dev client ID. - **redirect_uri** (string) - Required - The URI to redirect to after authentication. - **response_type** (string) - Required - Should be 'code'. - **scope** (string) - Optional - The scopes requested (e.g., 'openid email profile'). - **state** (string) - Optional - An opaque value used to maintain state between the request and callback. - **code_challenge** (string) - Required for PKCE - The code challenge for Proof Key for Code Exchange. - **code_challenge_method** (string) - Required for PKCE - The method used for the code challenge (e.g., 'S256'). ### Response #### Redirect Redirects the user to the Shoo.dev login page or directly to the `redirect_uri` if already authenticated and consented. ## POST /token ### Description Exchanges an authorization code for an `id_token`. This endpoint is CORS-enabled. ### Method POST ### Endpoint /token ### Parameters #### Request Body - **grant_type** (string) - Required - Should be 'authorization_code'. - **code** (string) - Required - The authorization code received from the /authorize endpoint. - **redirect_uri** (string) - Required - The same redirect URI used in the authorization request. - **client_id** (string) - Required - Your Shoo.dev client ID. - **code_verifier** (string) - Required for PKCE - The code verifier corresponding to the `code_challenge`. ### Response #### Success Response (200) - **id_token** (string) - The JWT ID token. - **token_type** (string) - Typically 'Bearer'. - **expires_in** (integer) - The lifetime in seconds of the access token. #### Response Example ```json { "id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600 } ``` ## GET /.well-known/jwks.json ### Description Provides the public signing keys used to verify Shoo `id_token` signatures. ### Method GET ### Endpoint /.well-known/jwks.json ### Response #### Success Response (200) - **keys** (array) - An array of JWK public keys. #### Response Example ```json { "keys": [ { "kty": "RSA", "use": "sig", "kid": "some-key-id", "n": "...", "e": "AQAB" } ] } ``` ## GET /.well-known/openid-configuration ### Description OpenID Connect discovery document, providing metadata about the Shoo.dev authorization server. ### Method GET ### Endpoint /.well-known/openid-configuration ### Response #### Success Response (200) - **issuer** (string) - The issuer identifier. - **authorization_endpoint** (string) - The authorization server's authorization endpoint. - **token_endpoint** (string) - The authorization server's token endpoint. - **jwks_uri** (string) - The location of the JWK Set. - **response_types_supported** (array) - The response types supported. - **subject_types_supported** (array) - The subject types supported. - **id_token_signing_alg_values_supported** (array) - The JWS signing algorithms supported. #### Response Example ```json { "issuer": "https://shoo.dev", "authorization_endpoint": "https://shoo.dev/authorize", "token_endpoint": "https://shoo.dev/token", "jwks_uri": "https://shoo.dev/.well-known/jwks.json", "response_types_supported": ["code"], "subject_types_supported": ["public"], "id_token_signing_alg_values_supported": ["RS256"] } ``` ``` -------------------------------- ### PKCE (Proof Key for Code Exchange) Source: https://docs.shoo.dev/docs/how-it-works Explains the PKCE flow, a security measure to prevent authorization code interception, crucial for browser-based applications. ```APIDOC ## PKCE (Proof Key for Code Exchange) ### Description PKCE is a security extension to the OAuth 2.0 authorization code flow that prevents authorization code interception attacks. It is particularly important for public clients like single-page applications (SPAs) that cannot securely store a client secret. Shoo enforces the **S256** (SHA-256) challenge method for all flows. ### Flow 1. **Client generates `code_verifier`**: A random string (minimum 43 characters, maximum 128 characters). 2. **Client computes `code_challenge`**: The SHA-256 hash of the `code_verifier`, then Base64 URL encoded. 3. **Client sends `code_challenge`**: Included in the `/authorize` request. 4. **Shoo stores `code_challenge`**: Associated with the authorization code. 5. **Client sends `code_verifier`**: Included in the `/token` request when exchanging the authorization code. 6. **Shoo verifies**: Shoo hashes the received `code_verifier` and compares it to the stored `code_challenge`. If they match, the exchange is valid. ### Key Points - The `code_verifier` never leaves the browser tab where it was generated (typically stored in `sessionStorage`). - Intercepting the authorization code is useless without the `code_verifier`. ``` -------------------------------- ### Token Signing and Verification Source: https://docs.shoo.dev/docs/how-it-works Details how Shoo signs ID tokens using ES256 and provides information on public key distribution and OpenID configuration for verification. ```APIDOC ## Token Signing and Verification ### Description Shoo signs the `id_token` using the **ES256** (ECDSA with the P-256 curve) algorithm. This ensures the integrity and authenticity of the token. Public keys for verification are available at a well-known endpoint, and OpenID Connect discovery information is also provided. ### Token Signing - **Algorithm**: ES256 (ECDSA with P-256 curve) - **JWT Header**: Includes a `kid` (key ID) for key rotation purposes. ### Public Key Distribution - **JWKS Endpoint**: Public keys used for signing tokens are published at: `/.well-known/jwks.json` ### OpenID Configuration - **Discovery Endpoint**: OpenID Connect discovery information, including the JWKS URI, is available at: `/.well-known/openid-configuration` ### Server-Side Verification When you receive an `id_token` on your server, you **must** perform the following verification steps: 1. **Verify Signature**: Use the public keys from `/.well-known/jwks.json` to verify the token's signature. Ensure the `kid` in the token header matches the key used for verification. 2. **Verify Issuer (`iss`)**: Check that the issuer claim in the token matches the expected Shoo issuer URL (e.g., `https://shoo.dev`). 3. **Verify Audience (`aud`)**: Ensure the audience claim in the token includes your application's `client_id` (e.g., `origin:https://myapp.com`). 4. **Verify Expiration (`exp`)**: Check that the token has not expired. ``` -------------------------------- ### Authentication Flows Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Functions for initiating sign-in, handling callbacks, and exchanging authorization codes. ```APIDOC ## client.exchangeCode(params) ### Description Exchanges an authorization code for an `id_token` via `POST /token`. ### Method `exchangeCode` ### Parameters #### Request Body - **params** (ExchangeCodeParams) - Required - Parameters for the code exchange. - **shooBaseUrl** (string) - Required - The base URL of the Shoo service. - **clientId** (string) - Required - The client ID for your application. - **redirectUri** (string) - Required - The redirect URI registered with Shoo. - **code** (string) - Required - The authorization code received. - **codeVerifier** (string) - Required - The PKCE code verifier. ### Request Example ```javascript const token = await auth.exchangeCode({ shooBaseUrl: "https://shoo.dev", clientId: "origin:https://myapp.com", redirectUri: "https://myapp.com/auth/callback", code: "the_auth_code", codeVerifier: "the_pkce_verifier", }); ``` ### Response #### Success Response (200) - **TokenResponse** - The token response object. - **token_type** (string) - Always "Bearer". - **expires_in** (number) - Token lifetime in seconds. - **pairwise_sub** (string) - Domain-scoped user ID. - **id_token** (string) - Signed JWT. ## client.createPkceBundle() ### Description Generates a PKCE bundle with a random state, verifier, and S256 challenge. ### Method `createPkceBundle` ### Request Example ```javascript const bundle = await auth.createPkceBundle(); // { state: "...", verifier: "...", challenge: "..." } ``` ### Response #### Success Response (200) - **PkceBundle** - An object containing state, verifier, and challenge. ## client.createSignInUrl(params) ### Description Builds an authorize URL without navigating. Useful for custom sign-in flows. ### Method `createSignInUrl` ### Parameters #### Request Body - **params** (StartSignInOptions) - Required - Options for creating the sign-in URL. - **state** (string) - Required - The state parameter for the OAuth flow. - **codeChallenge** (string) - Required - The PKCE code challenge. ### Request Example ```javascript const url = auth.createSignInUrl({ state: bundle.state, codeChallenge: bundle.challenge, }); ``` ### Response #### Success Response (200) - **string** - The generated sign-in URL. ## client.parseCallback(url?) ### Description Extracts `code` and `state` from a callback URL. Returns `null` if no callback params are present. ### Method `parseCallback` ### Parameters #### Path Parameters - **url** (string) - Optional - The callback URL to parse. Defaults to the current window location. ### Response #### Success Response (200) - **{ code: string, state: string } | null** - An object containing the code and state, or null. ## client.clearCallbackParams() ### Description Removes `code`, `state`, and `error` from the browser URL bar using `history.replaceState`. ### Method `clearCallbackParams` ``` -------------------------------- ### Integrate Shoo Auth with ConvexProviderWithAuth Source: https://docs.shoo.dev/docs/api-reference/shoo-react Shows how to integrate the Shoo authentication adapter with Convex's `ConvexProviderWithAuth`. It initializes a `ConvexReactClient` and passes the custom `useAuth` hook to the provider. ```jsx import { ConvexProviderWithAuth, ConvexReactClient } from "convex/react"; import { useAuth } from "./shoo"; const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL); export function Providers({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` -------------------------------- ### Finish Sign-In (Lower-Level Callback Handling) Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Provides a lower-level method for handling the authentication callback without automatic redirection. This is useful when more control over the post-authentication flow is needed. It performs the code exchange and can optionally clear callback parameters from the URL and redirect after completion. ```javascript const token = await auth.finishSignIn({ redirectAfter: false, }); ``` -------------------------------- ### Standalone Functions Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Utility functions exported at the top level for use without a client instance. ```APIDOC ## deriveClientIdFromRedirectUri(redirectUri) ### Description Computes the client ID from a redirect URI: `"origin:" + new URL(redirectUri).origin`. ### Method `deriveClientIdFromRedirectUri` ### Parameters #### Path Parameters - **redirectUri** (string) - Required - The redirect URI. ### Response #### Success Response (200) - **string** - The derived client ID. ``` -------------------------------- ### Implement Sign In and Sign Out Buttons Source: https://docs.shoo.dev/docs/convex Provides buttons for users to initiate the sign-in and sign-out processes using the functions exported from the Shoo auth module. ```typescript import { signIn, signOut } from "./shoo"; function AuthButtons() { return (
); } ``` -------------------------------- ### ConvexAuth Integration Source: https://docs.shoo.dev/docs/api-reference/shoo-react Details on how to create and use Convex authentication with the `createShooConvexAuth` function and its integration with `ConvexProviderWithAuth`. ```APIDOC ## ConvexAuth ### Description Creates and integrates Convex authentication for your application. ### Method `createShooConvexAuth(options)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **options** (object) - Required - Configuration options for ConvexAuth. * **convexClient** (ConvexClient) - The Convex client instance. * **shooAuthOptions** (object) - Options for Shoo authentication (see `useShooAuth` for details). ### Return Value * **useAuth** (function) - A hook that returns authentication status and related functions. ### Usage with ConvexProviderWithAuth To use Convex authentication, you typically wrap your application with `ConvexProviderWithAuth` and provide the authentication logic created by `createShooConvexAuth`. ### Example ```javascript import { ConvexProvider, ConvexReactClient } from 'convex/react'; import { ConvexProviderWithAuth } from 'convex/react-convex-websocket'; import { createShooConvexAuth } from 'shoo-auth'; const convex = new ConvexReactClient('YOUR_CONVEX_URL'); const { useAuth } = createShooConvexAuth({ convexClient: convex, shooAuthOptions: { redirectUri: 'http://localhost:3000/callback', clientId: 'your-client-id' } }); function App() { return ( {/* Your application components */} ); } export default App; ``` ### useAuth() return value The `useAuth` hook, returned by `createShooConvexAuth`, provides the following: * **isLoading** (boolean): True if authentication is currently being processed. * **isAuthenticated** (boolean): True if the user is authenticated. * **user** (object | null): The authenticated user object, or null if not authenticated. * **login** (function): Function to initiate the login process. * **logout** (function): Function to initiate the logout process. ``` -------------------------------- ### Create Sign-In URL Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Builds an authorization URL without navigating the user. This is useful for implementing custom sign-in flows where you need to control the redirection process. ```javascript const url = auth.createSignInUrl({ state: bundle.state, codeChallenge: bundle.challenge, }); ``` -------------------------------- ### Wire up Shoo Auth Provider with Convex Source: https://docs.shoo.dev/docs/convex Connects the Shoo authentication module to the Convex provider. This ensures that Convex can utilize the authentication state managed by Shoo. ```typescript import { ConvexProviderWithAuth, ConvexReactClient } from "convex/react"; import { useAuth } from "./shoo"; const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL); function Root() { return ( ); } ``` -------------------------------- ### Access User Identity in Convex Functions Source: https://docs.shoo.dev/docs/convex Demonstrates how to access the authenticated user's identity within Convex server functions. It retrieves the stable user ID, email, and name from the authentication context. ```typescript import { query } from "./_generated/server"; export const viewer = query({ args: {}, handler: async (ctx) => { const identity = await ctx.auth.getUserIdentity(); if (!identity) return null; return { userId: identity.subject, email: identity.email ?? null, name: identity.name ?? null, }; }, }); ``` -------------------------------- ### Import Standalone Authentication Functions Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Imports top-level standalone authentication functions from the `@shoojs/auth` package, allowing their use without instantiating a client. ```javascript import { createPkceBundle, createSignInUrl, parseCallback, clearCallbackParams, getIdentity, persistIdentity, clearIdentity, decodeIdentityClaims, exchangeCode, deriveClientIdFromRedirectUri, } from "@shoojs/auth"; ``` -------------------------------- ### Token Verification with jose Library Source: https://docs.shoo.dev/docs/server-verification This section details how to use the 'jose' library in your server-side application to verify Shoo ID tokens. It covers fetching JWKS, verifying token signatures, issuer, audience, and expiration. ```APIDOC ## Token Verification with jose Library ### Description This section details how to use the 'jose' library in your server-side application to verify Shoo ID tokens. It covers fetching JWKS, verifying token signatures, issuer, audience, and expiration. ### Method POST (for `jwtVerify` function) ### Endpoint N/A (This is a server-side code example) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body (for `jwtVerify` function) - **idToken** (string) - Required - The ID token received from Shoo. - **appOrigin** (string) - Required - The origin of your application (e.g., `https://your-app.com`). ### Request Example ```typescript import { createRemoteJWKSet, jwtVerify } from "jose"; const SHOO_BASE_URL = "https://shoo.dev"; const SHOO_ISSUER = "https://shoo.dev"; const jwks = createRemoteJWKSet( new URL("/.well-known/jwks.json", SHOO_BASE_URL), ); export async function verifyShooToken(idToken: string, appOrigin: string) { const audience = `origin:${new URL(appOrigin).origin}`; const { payload } = await jwtVerify(idToken, jwks, { issuer: SHOO_ISSUER, audience, }); if (typeof payload.pairwise_sub !== "string") { throw new Error("Shoo token missing pairwise_sub"); } return payload; } ``` ### Response #### Success Response (200) - **payload** (object) - The decoded and verified payload of the ID token, including claims like `pairwise_sub`. #### Response Example ```json { "iss": "https://shoo.dev", "aud": "origin:https://your-app.com", "sub": "some_user_id", "pairwise_sub": "some_user_id", "iat": 1678886400, "exp": 1678890000, "jti": "some_jwt_id", "email": "user@example.com", "name": "John Doe" } ``` #### Error Response - **Error** (object) - An error object if verification fails (e.g., invalid signature, expired token, incorrect issuer/audience). #### Error Response Example ```json { "error": "invalid_token", "error_description": "Token signature verification failed." } ``` ``` -------------------------------- ### Create Convex Auth Adapter with Shoo Source: https://docs.shoo.dev/docs/api-reference/shoo-react Creates a Convex-compatible authentication adapter using `createShooConvexAuth`. This function should be called once at the module scope, and the returned `useAuth` hook is then passed to `ConvexProviderWithAuth`. ```ts import { createShooConvexAuth } from "@shoojs/react"; export const { useAuth, signIn, signOut } = createShooConvexAuth({ shooBaseUrl: "https://shoo.dev", callbackPath: "/shoo/callback", }); ``` -------------------------------- ### Create Shoo Convex Auth Module Source: https://docs.shoo.dev/docs/convex Creates a Shoo authentication module using `createShooConvexAuth`. This module exports hooks and functions for managing authentication state and actions within the application. ```typescript import { createShooConvexAuth } from "@shoojs/react"; export const { useAuth, signIn, signOut } = createShooConvexAuth({ callbackPath: "/shoo/callback", }); ``` -------------------------------- ### Send ID Token to Verification API from Client (JavaScript) Source: https://docs.shoo.dev/docs/server-verification This client-side JavaScript snippet demonstrates how to send an obtained `idToken` to the `/api/verify` endpoint using the `fetch` API. It makes a POST request with the token in JSON format and processes the response. This is typically done after a user signs in. ```javascript const identity = auth.identity; if (identity.token) { const res = await fetch("/api/verify", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ idToken: identity.token }), }); const data = await res.json(); // data.userId is now server-verified } ``` -------------------------------- ### Import Authentication Types Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Imports various TypeScript types related to Shoo authentication from the `@shoojs/auth` package. These types help in defining the structure of authentication-related data. ```typescript import type { PkceBundle, ShooIdentity, ShooAuthOptions, StartSignInOptions, ExchangeCodeParams, FinishSignInOptions, HandleCallbackOptions, ShooAuthClient, } from "@shoojs/auth"; ``` -------------------------------- ### Identity Management Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Functions for managing user identity, including clearing, decoding claims, and persisting identity information. ```APIDOC ## client.clearIdentity(storageKey?) ### Description Removes the persisted identity from `localStorage`. Use this for sign-out. ### Method `clearIdentity` ### Parameters #### Path Parameters - **storageKey** (string) - Optional - The key used for storing identity in localStorage. ### Request Example ```javascript auth.clearIdentity(); ``` ## client.decodeIdentityClaims(idToken?) ### Description Decodes the JWT payload **without verifying the signature**. For display purposes only — always verify tokens on your server. ### Method `decodeIdentityClaims` ### Parameters #### Path Parameters - **idToken** (string) - Optional - The ID token to decode. ### Request Example ```javascript const claims = auth.decodeIdentityClaims(); // { iss, aud, sub, pairwise_sub, iat, exp, jti, email?, name?, picture? } ``` ### Response #### Success Response (200) - **IdentityClaims | null** - The decoded claims or null if no token is found. ## client.getIdentity(storageKey?) ### Description Retrieves the persisted identity from `localStorage`. ### Method `getIdentity` ### Parameters #### Path Parameters - **storageKey** (string) - Optional - The key used for storing identity in localStorage. ### Response #### Success Response (200) - **ShooIdentity | null** - The persisted identity object or null if not found. ## client.persistIdentity(userId, token, storageKey?, extras?) ### Description Persists the user identity to `localStorage`. ### Method `persistIdentity` ### Parameters #### Path Parameters - **userId** (string) - Required - The unique identifier for the user. - **token** (string) - Required - The authentication token. - **storageKey** (string) - Optional - The key used for storing identity in localStorage. - **extras** (object) - Optional - Additional data to store with the identity. ``` -------------------------------- ### Handle Authentication Callback Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Processes the callback from Shoo after successful authentication. This high-level handler exchanges the authorization code for tokens, persists the user's identity, and redirects the browser to the stored return-to URL. It can optionally parse a specific URL or define an explicit redirect target. ```javascript const token = await auth.handleCallback(); // Browser redirects after this call ``` -------------------------------- ### Use Shoo Authentication Hook in React Source: https://docs.shoo.dev/docs/api-reference/shoo-react Demonstrates the basic usage of the `useShooAuth` hook in a React component. It provides state variables for identity, claims, loading, and errors, along with functions to manage the authentication flow. ```jsx import { useShooAuth } from "@shoojs/react"; function App() { const { identity, claims, loading, error, signIn, handleCallback, refreshIdentity, clearIdentity, authClient, } = useShooAuth(); } ``` -------------------------------- ### Sign Out (Vanilla JS) Source: https://docs.shoo.dev/docs/getting-started-vanilla Clear the user's identity information from local storage to sign them out of the application. This function removes stored tokens and user data. ```javascript window.Shoo.clearIdentity(); ``` -------------------------------- ### Verify Shoo.dev ID Token in Next.js API Route (TypeScript) Source: https://docs.shoo.dev/docs/server-verification This API route, written in TypeScript for Next.js, accepts an `id_token` via POST request, verifies its authenticity and claims using Shoo.dev's JWKS endpoint and the 'jose' library, and returns verified user information. It handles method validation, token presence checks, and error handling during verification. Dependencies include 'next' and 'jose'. ```typescript import type { NextApiRequest, NextApiResponse } from "next"; import { createRemoteJWKSet, jwtVerify } from "jose"; const SHOO_BASE_URL = process.env.SHOO_BASE_URL || "https://shoo.dev"; const SHOO_ISSUER = process.env.SHOO_ISSUER || SHOO_BASE_URL; const APP_ORIGIN = process.env.APP_ORIGIN || "http://localhost:3000"; const jwks = createRemoteJWKSet( new URL("/.well-known/jwks.json", SHOO_BASE_URL), ); export default async function handler( req: NextApiRequest, res: NextApiResponse, ) { if (req.method !== "POST") { return res.status(405).json({ error: "Method not allowed" }); } const idToken = typeof req.body?.idToken === "string" ? req.body.idToken : ""; if (!idToken) { return res.status(400).json({ error: "Missing idToken" }); } try { const audience = `origin:${new URL(APP_ORIGIN).origin}`; const { payload } = await jwtVerify(idToken, jwks, { issuer: SHOO_ISSUER, audience, }); if (typeof payload.pairwise_sub !== "string") { return res.status(401).json({ error: "Missing pairwise_sub claim" }); } return res.status(200).json({ userId: payload.pairwise_sub, email: payload.email, name: payload.name, }); } catch (err) { const message = err instanceof Error ? err.message : "Verification failed"; return res.status(401).json({ error: message }); } } ``` -------------------------------- ### Re-exporting Shoo Auth Types and Functions Source: https://docs.shoo.dev/docs/api-reference/shoo-react Illustrates the re-exporting of core types and functions from the `@shoojs/auth` package for convenience within the `@shoojs/react` package. This includes functions for creating auth clients and decoding identity claims. ```ts import { createShooAuth, decodeIdentityClaims, } from "@shoojs/react"; import type { HandleCallbackOptions, ShooAuthClient, ShooAuthOptions, ShooIdentity, StartSignInOptions, TokenResponse, } from "@shoojs/react"; ``` -------------------------------- ### Exchange Authorization Code for Token Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Exchanges an authorization code for an `id_token` by making a `POST /token` request. This is a crucial step in the OAuth 2.0 authorization code flow. ```javascript const token = await auth.exchangeCode({ shooBaseUrl: "https://shoo.dev", clientId: "origin:https://myapp.com", redirectUri: "https://myapp.com/auth/callback", code: "the_auth_code", codeVerifier: "the_pkce_verifier", }); ``` -------------------------------- ### Persist User Identity Source: https://docs.shoo.dev/docs/api-reference/shoo-auth Writes the user's identity information, including their ID and authentication token, to `localStorage`. This function is typically called automatically by `handleCallback` and `finishSignIn` but can be used manually if needed. ```javascript auth.persistIdentity(userId, token, storageKey?, extras?) ```