feat: enhance auth schema and add CLI configuration

- Updated the user schema to include new fields: banned, banReason, and banExpires for improved user management.
- Introduced a new auth-cli configuration file to facilitate database schema generation and inspection for better-auth plugins.
- Ensured the CLI configuration mirrors the plugin set in auth.ts for consistency across the application.
This commit is contained in:
Mauricio Siu
2026-04-19 12:05:37 -06:00
parent f06c9deddf
commit 0dbd1039e8
2 changed files with 300 additions and 236 deletions

View File

@@ -1,11 +1,11 @@
import { relations } from "drizzle-orm";
import {
boolean,
index,
integer,
pgTable,
text,
timestamp,
boolean,
integer,
index,
uniqueIndex,
} from "drizzle-orm/pg-core";
@@ -22,6 +22,9 @@ export const user = pgTable("user", {
.notNull(),
twoFactorEnabled: boolean("two_factor_enabled").default(false),
role: text("role"),
banned: boolean("banned").default(false),
banReason: text("ban_reason"),
banExpires: timestamp("ban_expires"),
ownerId: text("owner_id"),
allowImpersonation: boolean("allow_impersonation").default(false),
lastName: text("last_name").default(""),
@@ -45,6 +48,7 @@ export const session = pgTable(
.notNull()
.references(() => user.id, { onDelete: "cascade" }),
activeOrganizationId: text("active_organization_id"),
impersonatedBy: text("impersonated_by"),
},
(table) => [index("session_userId_idx").on(table.userId)],
);
@@ -142,6 +146,7 @@ export const twoFactor = pgTable(
userId: text("user_id")
.notNull()
.references(() => user.id, { onDelete: "cascade" }),
verified: boolean("verified").default(true),
},
(table) => [
index("twoFactor_secret_idx").on(table.secret),
@@ -223,6 +228,13 @@ export const invitation = pgTable(
],
);
export const scimProvider = pgTable("scim_provider", {
id: text("id").primaryKey(),
providerId: text("provider_id").notNull().unique(),
scimToken: text("scim_token").notNull().unique(),
organizationId: text("organization_id"),
});
export const userRelations = relations(user, ({ many }) => ({
sessions: many(session),
accounts: many(account),

View File

@@ -0,0 +1,52 @@
import { apiKey } from "@better-auth/api-key";
import { scim } from "@better-auth/scim";
import { sso } from "@better-auth/sso";
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { admin, organization, twoFactor } from "better-auth/plugins";
import { db } from "../db";
import * as schema from "../db/schema";
import { ac, adminRole, memberRole, ownerRole } from "./access-control";
/**
* Minimal better-auth config used only by `@better-auth/cli` to generate /
* inspect database schemas. Must mirror the plugin set in `auth.ts` so the CLI
* sees every table each plugin expects.
*
* Do NOT import this file from the runtime — use `auth.ts` for that.
*/
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "pg",
schema,
}),
user: {
modelName: "user",
fields: {
name: "firstName",
},
additionalFields: {
role: { type: "string", input: false },
ownerId: { type: "string", input: false },
allowImpersonation: { type: "boolean", defaultValue: false },
lastName: { type: "string", required: false, defaultValue: "" },
enableEnterpriseFeatures: { type: "boolean", required: false },
isValidEnterpriseLicense: { type: "boolean", required: false },
},
},
plugins: [
apiKey({ enableMetadata: true, references: "user" }),
sso(),
twoFactor(),
organization({
ac,
roles: { owner: ownerRole, admin: adminRole, member: memberRole },
dynamicAccessControl: {
enabled: true,
maximumRolesPerOrganization: 10,
},
}),
scim(),
admin(),
],
});