Admin dashboard

Managing users

Find, add, edit, ban and delete users, and help them when they're locked out.
The users list: each user's role, status, email, sign-in methods, last active and last sign-in

The users list

  • Search by email or name, filter (admins, staff, banned, unverified, guests, two-factor off), sort and page through.
  • Select rows to ban or delete several users at once.
  • Columns show each user's sign-in methods (a key for email and password, a logo per provider, so users who only sign in with a provider stand out), two-factor, and, with the audit log, their last sign-in.

Adding a user

Add user asks for a name, email, an optional password and a role. "New user" on the home page, or /admin/users?create=1, opens it straight away. Once created, the toast links to their page.

Exporting and importing

Export

Export on the users list downloads every user as a CSV file (users-<date>.csv), for staff who can list users. It has:

  • name, email, emailVerified and role first: the columns the import reads, so an export can be imported elsewhere;
  • their username, your app's own user fields, and the plugins' fields (phone number, two-factor, guest);
  • Better Auth's id, ban details and dates;
  • signInMethods: their providers, with credential for email and password.

Never passwords, tokens or secrets. Text a spreadsheet would run as a formula (starting with =, +, - or @) is written with a leading ', so opening the file can't run anything. Each export is recorded in the audit log.

Import

Import creates users from a CSV file, for staff who can create users. The file needs a header row and an email column. It reads:

ColumnWhat it is
emailRequired. Emails that already have an account are skipped, never changed.
nameDefaults to the email's first part.
passwordOptional, within your app's length rules. Without one, people sign in another way or set one.
roleOptional; several comma-separated. Staff need set-role to give roles.
emailVerifiedtrue, yes or 1 marks the email verified.
usernameWith usernames on, checked as Better Auth checks them.
Your fieldsYour app's own user fields, by name, in their types.

Header names match in any case, with or without spaces and underscores (Email, email_verified). Other columns are ignored, and the dialog says which.

  1. Choose the file. The dialog reads it in the browser and says how many users it will create.
  2. Optionally, email the people without a password a link to set one (with reset emails set up).
  3. Import. Then it lists what happened to each row: created, skipped (already has an account, or earlier in the file) or not created, and why.

Users are created through Better Auth's own createUser, with your session, so Better Auth checks the permissions and each user created is in the audit log, as when you add one by hand. Up to 1000 users per file.

A user's page

A user's admin page: profile, role and status, with their sign-in methods and sessions

Their profile, role and status, ban details, sign-in methods, and active sessions with device, IP and last activity. Depending on what's on, also: their username, phone number, organizations, subscription, API keys, your app's own user fields, staff notes, and their history from the audit log.

What staff can do

From the row menu on the list, or the user's page:

  • edit their name, email, avatar and whether the email is verified;
  • change their role;
  • set a password, or email them a reset link;
  • resend the verification email to an unverified user;
  • ban them, with a reason and an expiry, or unban them;
  • sign them out of one session, or everywhere;
  • remove a sign-in method;
  • delete them.

Staff see only the actions their role allows. Nobody can ban, delete or change the role of their own account here, and Better Auth refuses self-bans too.

Better Auth only lets signed-in users resend a verification email to themselves, so the module sends it on the server with auth.api.sendVerificationEmail, through your own email and template.

Removing a sign-in method

An old Google link, or their password, from the method's menu. As with Better Auth's own unlink endpoint, the last one can't be removed, since it would lock them out, unless your Better Auth config sets account.accountLinking.allowUnlinkingAll.

Lost a device?

With two-factor or passkeys on, each user's page has a Security card:

  • Turn their two-factor off. Their authenticator app, backup codes and trusted devices stop working. Users who must have two-factor are asked to set it up again.
  • Remove a passkey.

Better Auth has no admin endpoints for these, so the module does what its plugins' own disable and delete do, after checking the user: update permission. Both are recorded in the audit log.

Signing in as a user

Impersonation lets an admin see the app as a user does. Turn it on, and add the banner to your app's layout:

export default defineNuxtConfig({
  betterAuthUi: {
    admin: { impersonation: true }
  }
})

Sign in as is then in the row menu and on each user's page. It's Better Auth's impersonation: a one-hour session that keeps yours to return to, marked as an impersonation in their sessions list. Stop impersonating brings you back to their admin page. Admins and banned users can't be impersonated.

With impersonation off, the module also refuses Better Auth's impersonate-user endpoint, since Better Auth's default admin role is otherwise allowed to use it.

Staff notes

Private notes on each user's page, like "Warned for spam in chat", newest first, with who wrote each and when.

nuxt.config.ts
export default defineNuxtConfig({
  betterAuthUi: {
    admin: { notes: true }
  }
})
Staff who canCan
View users (user: get)Read notes
Update users (user: update)Add notes, and delete their own
Delete users (user: delete)Delete anyone's notes

Users never see them, and they're left out of a user's data download. Adding and deleting are recorded in the audit log, without the note's text. They're stored in an adminUserNote table (run Better Auth's migrations), and go when the user is deleted.

Your app's own user fields

Better Auth's user.additionalFields (a company, a plan, a region) show in a More details card on each user's page. Staff who can update users edit them, with an input per type: text, number, date, a switch, a select for a list of values, commas for lists.

  • Server-owned fields (input: false) are shown, not edited.
  • Hidden fields (returned: false) aren't shown, as Better Auth never returns them.
  • Labels come from the field names: favoriteColor shows as "Favorite color".