Skip to content
Migrating from NextAuth.js v4? Read our migration guide.
API reference
@auth/typeorm-adapter

@auth/typeorm-adapter

Official TypeORM adapter for Auth.js / NextAuth.js.

Installation

npm install @auth/typeorm-adapter typeorm

TypeORMAdapterOptions

This is the interface for the TypeORM adapter options.

Properties

entities?

optional entities: entities;

The TypeORM entities to create the database tables from.


Entities

type Entities: typeof entities;

entities

const entities: entities = defaultEntities;

TypeORMAdapter()

TypeORMAdapter(dataSource, options?): Adapter

Setup

Configure Auth.js to use the TypeORM Adapter:

pages/api/auth/[...nextauth].ts
import NextAuth from "next-auth"
import { TypeORMAdapter } from "@auth/typeorm-adapter"
 
export default NextAuth({
  adapter: TypeORMAdapter("yourconnectionstring"),
})

TypeORMAdapter takes either a connection string, or a ConnectionOptions object as its first parameter.

Advanced usage

Custom models

The TypeORM adapter uses Entity classes to define the shape of your data.

If you want to override the default entities (for example to add a role field to your UserEntity), you will have to do the following:

  1. Create a file containing your modified entities:

(The file below is based on the default entities)

lib/entities.ts
import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  ManyToOne,
  OneToMany,
  ValueTransformer,
} from "typeorm"
 
const transformer: Record<"date" | "bigint", ValueTransformer> = {
  date: {
    from: (date: string | null) => date && new Date(parseInt(date, 10)),
    to: (date?: Date) => date?.valueOf().toString(),
  },
  bigint: {
    from: (bigInt: string | null) => bigInt && parseInt(bigInt, 10),
    to: (bigInt?: number) => bigInt?.toString(),
  },
}
 
@Entity({ name: "users" })
export class UserEntity {
  @PrimaryGeneratedColumn("uuid")
  id!: string
 
  @Column({ type: "varchar", nullable: true })
  name!: string | null
 
  @Column({ type: "varchar", nullable: true, unique: true })
  email!: string | null
 
  @Column({ type: "varchar", nullable: true, transformer: transformer.date })
  emailVerified!: string | null
 
  @Column({ type: "varchar", nullable: true })
  image!: string | null
 
  @Column({ type: "varchar", nullable: true })
  role!: string | null
 
  @OneToMany(() => SessionEntity, (session) => session.userId)
  sessions!: SessionEntity[]
 
  @OneToMany(() => AccountEntity, (account) => account.userId)
  accounts!: AccountEntity[]
}
 
@Entity({ name: "accounts" })
export class AccountEntity {
  @PrimaryGeneratedColumn("uuid")
  id!: string
 
  @Column({ type: "uuid" })
  userId!: string
 
  @Column()
  type!: string
 
  @Column()
  provider!: string
 
  @Column()
  providerAccountId!: string
 
  @Column({ type: "varchar", nullable: true })
  refresh_token!: string | null
 
  @Column({ type: "varchar", nullable: true })
  access_token!: string | null
 
  @Column({
    nullable: true,
    type: "bigint",
    transformer: transformer.bigint,
  })
  expires_at!: number | null
 
  @Column({ type: "varchar", nullable: true })
  token_type!: string | null
 
  @Column({ type: "varchar", nullable: true })
  scope!: string | null
 
  @Column({ type: "varchar", nullable: true })
  id_token!: string | null
 
  @Column({ type: "varchar", nullable: true })
  session_state!: string | null
 
  @Column({ type: "varchar", nullable: true })
  oauth_token_secret!: string | null
 
  @Column({ type: "varchar", nullable: true })
  oauth_token!: string | null
 
  @ManyToOne(() => UserEntity, (user) => user.accounts, {
    createForeignKeyConstraints: true,
  })
  user!: UserEntity
}
 
@Entity({ name: "sessions" })
export class SessionEntity {
  @PrimaryGeneratedColumn("uuid")
  id!: string
 
  @Column({ unique: true })
  sessionToken!: string
 
  @Column({ type: "uuid" })
  userId!: string
 
  @Column({ transformer: transformer.date })
  expires!: string
 
  @ManyToOne(() => UserEntity, (user) => user.sessions)
  user!: UserEntity
}
 
@Entity({ name: "verification_tokens" })
export class VerificationTokenEntity {
  @PrimaryGeneratedColumn("uuid")
  id!: string
 
  @Column()
  token!: string
 
  @Column()
  identifier!: string
 
  @Column({ transformer: transformer.date })
  expires!: string
}
  1. Pass them to TypeORMAdapter
pages/api/auth/[...nextauth].js
import NextAuth from "next-auth"
import { TypeORMAdapter } from "@auth/typeorm-adapter"
import * as entities from "lib/entities"
 
export default NextAuth({
  adapter: TypeORMAdapter("yourconnectionstring", { entities })
})
💡

Synchronize your database The synchronize: true option in TypeORM will generate SQL that exactly matches the entities. This will automatically apply any changes it finds in the entity model. This is a useful option in development.

⚠️

Using synchronize in production The option synchronize: true should not be enabled against production databases as it may cause data loss if the configured schema does not match the expected schema! We recommend that you synchronize/migrate your production database at build-time.

Naming Conventions

If mixed snake_case and camelCase column names are an issue for you and/or your underlying database system, we recommend using TypeORM’s naming strategy feature to change the target field names. There is a package called typeorm-naming-strategies which includes a snake_case strategy which will translate the fields from how Auth.js expects them, to snake_case in the actual database.

For example, you can add the naming convention option to the connection object in your NextAuth config.

pages/api/auth/[...nextauth].js
import NextAuth from "next-auth"
import { TypeORMAdapter } from "@auth/typeorm-adapter"
import { SnakeNamingStrategy } from 'typeorm-naming-strategies'
import { ConnectionOptions } from "typeorm"
 
const connection: ConnectionOptions = {
  type: "mysql",
  host: "localhost",
  port: 3306,
  username: "test",
  password: "test",
  database: "test",
  namingStrategy: new SnakeNamingStrategy()
}
 
export default NextAuth({
  adapter: TypeORMAdapter(connection)
})

Parameters

ParameterType
dataSourcestring | DataSourceOptions
options?TypeORMAdapterOptions

Returns

Adapter


getManager()

getManager(options): Promise<EntityManager>

Parameters

ParameterType
optionsObject
options.dataSourcestring | DataSourceOptions
options.entitiesentities

Returns

Promise<EntityManager>

Auth.js © Balázs Orbán and Team - 2024