mirror of
https://github.com/better-auth/better-auth.git
synced 2026-08-01 10:50:40 -05:00
chore: refactor admin plugin schema (#3371)
* admin plugin type isolation * lint * import * import
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { getTestInstance } from "../../test-utils/test-instance";
|
||||
import { admin, type UserWithRole } from "./admin";
|
||||
import { admin } from "./admin";
|
||||
import { type UserWithRole } from "./types";
|
||||
import { adminClient } from "./client";
|
||||
import { createAccessControl } from "../access";
|
||||
import { createAuthClient } from "../../client";
|
||||
|
||||
@@ -5,101 +5,22 @@ import {
|
||||
createAuthMiddleware,
|
||||
getSessionFromCtx,
|
||||
} from "../../api";
|
||||
import {
|
||||
type BetterAuthPlugin,
|
||||
type InferOptionSchema,
|
||||
type AuthPluginSchema,
|
||||
type Session,
|
||||
type User,
|
||||
type Where,
|
||||
} from "../../types";
|
||||
import { type BetterAuthPlugin, type Session, type Where } from "../../types";
|
||||
import { deleteSessionCookie, setSessionCookie } from "../../cookies";
|
||||
import { getDate } from "../../utils/date";
|
||||
import { getEndpointResponse } from "../../utils/plugin-helper";
|
||||
import { mergeSchema } from "../../db/schema";
|
||||
import { type AccessControl, type Role } from "../access";
|
||||
import { type AccessControl } from "../access";
|
||||
import { ADMIN_ERROR_CODES } from "./error-codes";
|
||||
import { defaultStatements } from "./access";
|
||||
import { hasPermission } from "./has-permission";
|
||||
|
||||
export interface UserWithRole extends User {
|
||||
role?: string;
|
||||
banned?: boolean | null;
|
||||
banReason?: string | null;
|
||||
banExpires?: Date | null;
|
||||
}
|
||||
|
||||
export interface SessionWithImpersonatedBy extends Session {
|
||||
impersonatedBy?: string;
|
||||
}
|
||||
|
||||
export interface AdminOptions {
|
||||
/**
|
||||
* The default role for a user
|
||||
*
|
||||
* @default "user"
|
||||
*/
|
||||
defaultRole?: string;
|
||||
/**
|
||||
* Roles that are considered admin roles.
|
||||
*
|
||||
* Any user role that isn't in this list, even if they have the permission,
|
||||
* will not be considered an admin.
|
||||
*
|
||||
* @default ["admin"]
|
||||
*/
|
||||
adminRoles?: string | string[];
|
||||
/**
|
||||
* A default ban reason
|
||||
*
|
||||
* By default, no reason is provided
|
||||
*/
|
||||
defaultBanReason?: string;
|
||||
/**
|
||||
* Number of seconds until the ban expires
|
||||
*
|
||||
* By default, the ban never expires
|
||||
*/
|
||||
defaultBanExpiresIn?: number;
|
||||
/**
|
||||
* Duration of the impersonation session in seconds
|
||||
*
|
||||
* By default, the impersonation session lasts 1 hour
|
||||
*/
|
||||
impersonationSessionDuration?: number;
|
||||
/**
|
||||
* Custom schema for the admin plugin
|
||||
*/
|
||||
schema?: InferOptionSchema<typeof schema>;
|
||||
/**
|
||||
* Configure the roles and permissions for the admin
|
||||
* plugin.
|
||||
*/
|
||||
ac?: AccessControl;
|
||||
/**
|
||||
* Custom permissions for roles.
|
||||
*/
|
||||
roles?: {
|
||||
[key in string]?: Role;
|
||||
};
|
||||
/**
|
||||
* List of user ids that should have admin access
|
||||
*
|
||||
* If this is set, the `adminRole` option is ignored
|
||||
*/
|
||||
adminUserIds?: string[];
|
||||
/**
|
||||
* Message to show when a user is banned
|
||||
*
|
||||
* By default, the message is "You have been banned from this application"
|
||||
*/
|
||||
bannedUserMessage?: string;
|
||||
}
|
||||
|
||||
export type InferAdminRolesFromOption<O extends AdminOptions | undefined> =
|
||||
O extends { roles: Record<string, unknown> }
|
||||
? keyof O["roles"]
|
||||
: "user" | "admin";
|
||||
import {
|
||||
type AdminOptions,
|
||||
type UserWithRole,
|
||||
type SessionWithImpersonatedBy,
|
||||
type InferAdminRolesFromOption,
|
||||
} from "./types";
|
||||
import { schema } from "./schema";
|
||||
|
||||
function parseRoles(roles: string | string[]): string {
|
||||
return Array.isArray(roles) ? roles.join(",") : roles;
|
||||
@@ -1383,39 +1304,3 @@ export const admin = <O extends AdminOptions>(options?: O) => {
|
||||
options: options as any,
|
||||
} satisfies BetterAuthPlugin;
|
||||
};
|
||||
|
||||
const schema = {
|
||||
user: {
|
||||
fields: {
|
||||
role: {
|
||||
type: "string",
|
||||
required: false,
|
||||
input: false,
|
||||
},
|
||||
banned: {
|
||||
type: "boolean",
|
||||
defaultValue: false,
|
||||
required: false,
|
||||
input: false,
|
||||
},
|
||||
banReason: {
|
||||
type: "string",
|
||||
required: false,
|
||||
input: false,
|
||||
},
|
||||
banExpires: {
|
||||
type: "date",
|
||||
required: false,
|
||||
input: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
session: {
|
||||
fields: {
|
||||
impersonatedBy: {
|
||||
type: "string",
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
} satisfies AuthPluginSchema;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { defaultRoles } from "./access";
|
||||
import type { AdminOptions } from "./admin";
|
||||
import type { AdminOptions } from "./types";
|
||||
|
||||
type PermissionExclusive =
|
||||
| {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { type AuthPluginSchema } from "../../types";
|
||||
|
||||
export const schema = {
|
||||
user: {
|
||||
fields: {
|
||||
role: {
|
||||
type: "string",
|
||||
required: false,
|
||||
input: false,
|
||||
},
|
||||
banned: {
|
||||
type: "boolean",
|
||||
defaultValue: false,
|
||||
required: false,
|
||||
input: false,
|
||||
},
|
||||
banReason: {
|
||||
type: "string",
|
||||
required: false,
|
||||
input: false,
|
||||
},
|
||||
banExpires: {
|
||||
type: "date",
|
||||
required: false,
|
||||
input: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
session: {
|
||||
fields: {
|
||||
impersonatedBy: {
|
||||
type: "string",
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
} satisfies AuthPluginSchema;
|
||||
|
||||
export type AdminSchema = typeof schema;
|
||||
@@ -0,0 +1,83 @@
|
||||
import { type Session, type User } from "../../types";
|
||||
import { type InferOptionSchema } from "../../types";
|
||||
import { type AccessControl, type Role } from "../access";
|
||||
import { type AdminSchema } from "./schema";
|
||||
|
||||
export interface UserWithRole extends User {
|
||||
role?: string;
|
||||
banned?: boolean | null;
|
||||
banReason?: string | null;
|
||||
banExpires?: Date | null;
|
||||
}
|
||||
|
||||
export interface SessionWithImpersonatedBy extends Session {
|
||||
impersonatedBy?: string;
|
||||
}
|
||||
|
||||
export interface AdminOptions {
|
||||
/**
|
||||
* The default role for a user
|
||||
*
|
||||
* @default "user"
|
||||
*/
|
||||
defaultRole?: string;
|
||||
/**
|
||||
* Roles that are considered admin roles.
|
||||
*
|
||||
* Any user role that isn't in this list, even if they have the permission,
|
||||
* will not be considered an admin.
|
||||
*
|
||||
* @default ["admin"]
|
||||
*/
|
||||
adminRoles?: string | string[];
|
||||
/**
|
||||
* A default ban reason
|
||||
*
|
||||
* By default, no reason is provided
|
||||
*/
|
||||
defaultBanReason?: string;
|
||||
/**
|
||||
* Number of seconds until the ban expires
|
||||
*
|
||||
* By default, the ban never expires
|
||||
*/
|
||||
defaultBanExpiresIn?: number;
|
||||
/**
|
||||
* Duration of the impersonation session in seconds
|
||||
*
|
||||
* By default, the impersonation session lasts 1 hour
|
||||
*/
|
||||
impersonationSessionDuration?: number;
|
||||
/**
|
||||
* Custom schema for the admin plugin
|
||||
*/
|
||||
schema?: InferOptionSchema<AdminSchema>;
|
||||
/**
|
||||
* Configure the roles and permissions for the admin
|
||||
* plugin.
|
||||
*/
|
||||
ac?: AccessControl;
|
||||
/**
|
||||
* Custom permissions for roles.
|
||||
*/
|
||||
roles?: {
|
||||
[key in string]?: Role;
|
||||
};
|
||||
/**
|
||||
* List of user ids that should have admin access
|
||||
*
|
||||
* If this is set, the `adminRole` option is ignored
|
||||
*/
|
||||
adminUserIds?: string[];
|
||||
/**
|
||||
* Message to show when a user is banned
|
||||
*
|
||||
* By default, the message is "You have been banned from this application"
|
||||
*/
|
||||
bannedUserMessage?: string;
|
||||
}
|
||||
|
||||
export type InferAdminRolesFromOption<O extends AdminOptions | undefined> =
|
||||
O extends { roles: Record<string, unknown> }
|
||||
? keyof O["roles"]
|
||||
: "user" | "admin";
|
||||
Reference in New Issue
Block a user