Administration

Login history

Track every successful login with IP address, user-agent, and application context. Available via the admin dashboard and API.

Auth Service records every successful login in the login_history table, which gives a history of successful authentication events (failed attempts are not recorded).

Data model

FieldTypeDescription
idUUIDPrimary key
userIdstringUser identifier
applicationIdUUID | nullApplication id (null for a direct sign-in that is not an OAuth token issuance). Set to null when the application is deleted
sessionIdstring | nullAssociated session ID (set on direct sign-ins, null on OAuth token issuance rows)
ipAddressstring | nullClient IP address, as captured on the session
userAgentstring | nullClient user-agent string
loggedAttimestampLogin timestamp (UTC)

How it works

Every successful login triggers an insert into login_history, updates the denormalised user.last_login_at timestamp and publishes a login.recorded event on the live-event channel. Both database writes happen in recordLogin(); the callers wrap it in a try/catch, so a failure is logged at warn level and does not block authentication. Auth Service does not purge login_history rows itself.

Two paths record a login:

  • Direct session creation — the BetterAuth session.create hook (admin dashboard sign-in, password login, social provider callback) records a row with the session id, IP and user agent from the new session, and applicationId null.
  • OAuth token issuance to an application — customAccessTokenClaims has no request context, so the row is written with applicationId set to the target application and no session id, IP or user-agent. recordLogin() then falls back to the user's most recent session (the same client that is signing in) to fill in the IP and user agent.

Admin API endpoints

List login history for a user in an application

GET /api/admin/applications/:id/users/:userId/history

Requires an admin or superadmin session. Returns paginated login history for the specified user within the specified application, newest first:

{
  "entries": [
    {
      "id": "uuid-1",
      "loggedAt": "2026-06-15T14:30:00Z",
      "ipAddress": "192.168.1.1",
      "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...",
      "sessionId": null
    },
    {
      "id": "uuid-2",
      "loggedAt": "2026-06-14T09:15:00Z",
      "ipAddress": "10.0.0.1",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel...)",
      "sessionId": null
    }
  ],
  "total": 42,
  "page": 1,
  "limit": 20
}

Query parameters

ParameterDefaultDescription
page1Page number
limit20Results per page (max 100)

Admin dashboard

The user detail view (/users/:id) lists the user's applications with the date of the last login on each. It has no login-history list of its own.

The application detail view (/applications/:id) has a Users tab whose rows carry the last login date, IP and device for that application, plus a per-row history icon that opens the paginated Login history modal (GET /api/admin/applications/:id/users/:userId/history). The modal shows each entry's time, IP address and browser / operating system, with a selectable page size. These are read from login_history filtered by applicationId, so a login on another application — or a direct sign-in with no application — never appears here.

The tab stays live while it is open: a login.recorded event (published on every successful login) refreshes the last-login columns, and the activity strip at the top of the page (online count, 7-day logins, sparkline) is refreshed both by that event and by a 30 s poll that absorbs session-expiry drift. The online figure of that strip counts the distinct users with a login event for the application in the last 24 hours.

Statistics endpoint

The login statistics endpoint provides a dense daily series, platform-wide or for one application:

GET /api/admin/stats/logins?range=7d|30d&appId=<uuid>

Requires an admin or superadmin session. Response:

{
  "range": "7d",
  "series": [
    { "date": "2026-06-11", "count": 42 },
    { "date": "2026-06-12", "count": 38 },
    { "date": "2026-06-13", "count": 55 },
    { "date": "2026-06-14", "count": 61 },
    { "date": "2026-06-15", "count": 47 },
    { "date": "2026-06-16", "count": 33 },
    { "date": "2026-06-17", "count": 28 }
  ],
  "total": 304
}
ParameterDefaultDescription
range7dTime range: 7d or 30d
appId—Filter by application UUID

The series is dense — days with no logins are filled with count: 0 so chart libraries render a continuous axis. Days are UTC days, and total is the sum of the series.

Use cases

  • Security auditing — review the IP addresses and user agents of past logins for a user on an application.
  • Compliance — keep a record of successful authentication events. Failed attempts are not recorded here.
  • Analytics — track login trends over time via the statistics endpoint.
  • Forensics — investigate a suspect account by reviewing its login history per application.
Copyright © 2026