# Methods

API reference for authentication methods available through the `useDeva()` hook.

***

## Overview

The SDK provides two primary authentication methods accessed via the `useDeva` hook:

* `login()` - Initiates OAuth authentication flow
* `logout()` - Revokes tokens and clears authentication state

***

## login()

Initiates the OAuth 2.0 + OIDC authentication flow with PKCE.

### Signature

```typescript
login: () => Promise<void>
```

### Usage

```tsx
import { useDeva } from "@bitplanet/deva-sdk";

function LoginButton() {
  const { login, isAuthenticated } = useDeva();

  if (isAuthenticated) {
    return null;
  }

  return <button onClick={login}>Login with Deva</button>;
}
```

### Behavior

**When Called:**

1. Clears any existing authentication state
2. Generates PKCE code verifier and challenge
3. Redirects browser to Deva authorization endpoint
4. User authenticates on Deva platform
5. User grants permissions to your app
6. Deva redirects back to your `redirectUri` with authorization code
7. SDK exchanges code for access and refresh tokens
8. SDK fetches user information
9. Tokens stored in sessionStorage
10. `isAuthenticated` becomes `true`

**Parameters:**

* None

**Returns:**

* `Promise<void>` - Resolves immediately after redirect

**Errors:**

* Throws if OpenID configuration not loaded
* Network errors handled internally with retries

### Example Flow

```tsx
function App() {
  const { login, isReady, isAuthenticated } = useDeva();

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

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

  return <Dashboard />;
}
```

***

## logout()

Revokes the access token and clears all authentication state.

### Signature

```typescript
logout: () => Promise<void>
```

### Usage

```tsx
import { useDeva } from "@bitplanet/deva-sdk";

function LogoutButton() {
  const { logout, user } = useDeva();

  return (
    <div>
      <span>Logged in as {user?.preferred_username}</span>
      <button onClick={logout}>Logout</button>
    </div>
  );
}
```

### Behavior

**When Called:**

1. Sends revocation request to Deva OAuth server
2. Clears sessionStorage (access\_token, refresh\_token, id\_token)
3. Resets internal authentication state
4. `isAuthenticated` becomes `false`
5. `user` becomes `null`
6. `accessToken` becomes `null`

**Parameters:**

* None

**Returns:**

* `Promise<void>` - Resolves when logout complete

**Errors:**

* Network errors logged but do not throw
* Logout completes even if revocation fails
* Local state always cleared

### Example with Confirmation

```tsx
function LogoutButton() {
  const { logout } = useDeva();
  const [isLoggingOut, setIsLoggingOut] = useState(false);

  const handleLogout = async () => {
    if (confirm("Are you sure you want to log out?")) {
      setIsLoggingOut(true);
      await logout();
      // Redirect or show message
    }
  };

  return (
    <button onClick={handleLogout} disabled={isLoggingOut}>
      {isLoggingOut ? "Logging out..." : "Logout"}
    </button>
  );
}
```

***

## Internal Methods

These methods are used internally by the SDK and not directly exposed:

### refreshToken()

**Purpose:** Automatically refreshes expired access tokens

**Behavior:**

* Called automatically before token expires
* Checks token expiration every second via `useInterval`
* Exchanges refresh\_token for new access\_token
* Updates sessionStorage with new tokens
* Happens transparently without user interaction

**When It Runs:**

* Token is about to expire (checked every second)
* Returns new tokens and updates state
* If refresh fails, user is logged out

### revokeToken()

**Purpose:** Revokes access token on logout

**Behavior:**

* Called by `logout()` method
* Sends POST request to revocation endpoint
* Includes access\_token and client\_id
* Invalidates token on server

***

## Authentication State

Access authentication state via `useDeva()` hook:

```typescript
const {
  isAuthenticated,  // true if user has valid token
  isReady,          // true when SDK initialized
  accessToken,      // current access token
  user,             // user information object
  login,            // login function
  logout            // logout function
} = useDeva();
```

### isAuthenticated

**Type:** `boolean`

**Values:**

* `true` - User has valid access token
* `false` - User not logged in or token expired

**Usage:**

```tsx
if (isAuthenticated) {
  return <AuthenticatedContent />;
}
return <LoginPrompt />;
```

### isReady

**Type:** `boolean`

**Values:**

* `true` - SDK initialization complete
* `false` - SDK still initializing

**Usage:**

```tsx
if (!isReady) {
  return <LoadingSpinner />;
}
// SDK ready, safe to check isAuthenticated
```

### accessToken

**Type:** `string | null`

**Value:** JWT access token or `null` if not authenticated

**Usage:**

```tsx
const { accessToken } = useDeva();

// Use for custom API calls
fetch("https://api.deva.me/custom", {
  headers: {
    Authorization: `Bearer ${accessToken}`
  }
});
```

**Note:** Components and hooks use this automatically. Manual use only needed for custom API calls.

***

## Authentication Patterns

### Protected Routes

```tsx
function ProtectedRoute({ children }) {
  const { isReady, isAuthenticated, login } = useDeva();

  if (!isReady) {
    return <LoadingScreen />;
  }

  if (!isAuthenticated) {
    return (
      <div>
        <p>Please log in to continue</p>
        <button onClick={login}>Login</button>
      </div>
    );
  }

  return <>{children}</>;
}
```

### Conditional Rendering

```tsx
function App() {
  const { isAuthenticated, login, logout } = useDeva();

  return (
    <div>
      <header>
        {isAuthenticated ? (
          <button onClick={logout}>Logout</button>
        ) : (
          <button onClick={login}>Login</button>
        )}
      </header>
      <main>
        {isAuthenticated ? <Dashboard /> : <LandingPage />}
      </main>
    </div>
  );
}
```

### Automatic Redirect

```tsx
function App() {
  const { isReady, isAuthenticated, login } = useDeva();

  useEffect(() => {
    if (isReady && !isAuthenticated) {
      login(); // Auto-redirect to login
    }
  }, [isReady, isAuthenticated, login]);

  if (!isReady || !isAuthenticated) {
    return <LoadingScreen />;
  }

  return <Dashboard />;
}
```

***

## Security Considerations

**Token Storage:**

* Tokens stored in sessionStorage (not localStorage)
* Cleared when browser/tab closes
* Not accessible to other domains

**PKCE Flow:**

* No client secret exposed in browser
* Code verifier prevents interception attacks
* State parameter prevents CSRF

**Automatic Refresh:**

* Tokens refreshed before expiration
* Seamless user experience
* No re-authentication required

**Best Practices:**

* Always use HTTPS in production
* Never log tokens to console
* Don't store tokens in component state
* Let SDK manage token lifecycle

***

## Related Documentation

* [useDeva Hook](/hooks-api/use-deva.md) - Complete hook reference
* [DevaProvider](/api-reference/deva-provider.md) - Provider configuration
* [OAuth Integration](/authentication/oauth-integration.md) - OAuth flow details
* [Authentication Flow](/core-concepts/authentication-flow.md) - How auth works
* [Session Persistence](/authentication/session-persistence.md) - Token storage


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sdkdocs.deva.me/api-reference/authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
