### 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?)
```