# Session Management

Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/session

Use `useSession` when an account screen needs the active profile or the user's
server-side sessions. It reads the active native `Ovok` client; your app still owns
route protection and the destination after sign-in or sign-out.

## Read session state [#read-session-state]

Render the hook below [`OvokProvider`](/native-sdk/guide/how-to/app-shell). This example
checks loading and errors before rendering a signed-out state.

```tsx
import { useSession } from "@ovok/native";
import { Button, Text } from "react-native-paper";

export function SecurityStatus() {
  const {
    status,
    reason,
    activeAccountId,
    patientId,
    sessions,
    loading,
    switching,
    error,
    refresh,
  } = useSession({ sessions: true, refreshOnForeground: true });

  if (loading) return <Text>Loading account…</Text>;

  if (error) {
    return (
      <>
        <Text>We couldn't refresh your account state.</Text>
        <Button onPress={() => void refresh()}>Try again</Button>
      </>
    );
  }

  if (status === "signed-out") {
    return (
      <Text>
        {reason === "session-ended"
          ? "Your session ended. Sign in again."
          : "Sign in to view account security."}
      </Text>
    );
  }

  return (
    <>
      <Text>Account: {activeAccountId}</Text>
      <Text>Patient: {patientId}</Text>
      <Text>Active sessions: {sessions.length}</Text>
      {switching && <Text>Updating account…</Text>}
    </>
  );
}
```

The hook returns `status` (`loading`, `authenticated`, `offline`, or `signed-out`),
`isAuthenticated`, `activeAccountId`, `patientId` when the active profile is a
Patient, saved `accounts`, `profile`, normalized `sessions`, `loading`,
`switching`, `reason`, `error`, `refresh`, `refreshSessions`, `switchAccount`,
`removeAccount`, `logout`, and `revokeSessions`. `offline` means the saved login is
still present but profile refresh failed; it remains authenticated. The hook
retries when connectivity returns. `reason` is `"session-ended"` when the client
clears an active login unexpectedly; it is absent after a user-requested logout.

## Refresh and revoke sessions [#refresh-and-revoke-sessions]

`sessions` and `refreshOnForeground` both default to `true`. Set `sessions: false`
when a screen only needs profile state. Set `refreshOnForeground: false` if the
host already refreshes on app resume. The hook also refreshes when a mounted
auth component publishes a session change; call `refresh()` after a custom auth
flow that does not publish that event.

`activeAccountId` identifies the selected saved account. When it changes, `profile`
is cleared until a profile can be matched to that account; if the identity cannot
be confirmed, `profile` and `patientId` are undefined. A failed refresh will not
expose the previous account's profile. `switchAccount()` and `removeAccount()`
preserve the current `status` while they run. Use `switching` to disable account
controls or show local progress; do not replace the screen or navigator based on
it. Removing an inactive account does not change the active session.

Account switching, saved accounts, and the `session-ended` reason use the
`@ovok/core/next` session methods and the native client's secure storage.


Use `revokeSessions("other")` to sign out other sessions. The server owns the
session inventory and revocation policy. The returned session fields are
`id`, `authMethod`, `remoteAddress`, and `lastUpdated` when the backend provides
them.

When the saved session remains present after a profile refresh failure, the hook
reports `status: "offline"` and exposes the failure as `error`. It reports
`signed-out` only when there is no current session. Its `logout()` method ends
the local session even when the server request fails; catch the returned promise
if the result affects navigation.

## Use the provided session list [#use-the-provided-session-list]

`<SessionList onError={handleError} />` renders the loading and empty states,
lists available sessions, and offers **Sign out of other devices** when more
than one session is present. It creates its own `useSession` hook; use the list
on its own or build a custom list from one hook instance rather than mounting
both and fetching sessions twice.

The session list calls `client.auth.sessions.list()` and the action calls
`client.auth.sessions.revoke("other")` on the active next client.

## Related guides [#related-guides]

- [Auth hooks and rate limits](/native-sdk/guide/components/auth/hooks/)
- [Logout button](/native-sdk/guide/components/auth/logout-button/)
