mirror of
https://github.com/LukeHagar/better-auth.git
synced 2025-12-10 04:19:32 +00:00
fix(admin): require adminRoles option for a role to be considered an admin role
This commit is contained in:
@@ -514,6 +514,20 @@ admin({
|
||||
defaultRole: "regular",
|
||||
});
|
||||
```
|
||||
### Admin Roles
|
||||
|
||||
The roles that are considered admin roles. Defaults to `["admin"]`.
|
||||
|
||||
```ts title="auth.ts"
|
||||
admin({
|
||||
adminRoles: ["admin", "superadmin"],
|
||||
});
|
||||
```
|
||||
|
||||
<Callout type="warning">
|
||||
Any role that isn't in the `adminRoles` list, even if they have the permission,
|
||||
will not be considered an admin.
|
||||
</Callout>
|
||||
|
||||
### Admin userIds
|
||||
|
||||
@@ -525,6 +539,8 @@ admin({
|
||||
})
|
||||
```
|
||||
|
||||
If a user is in the `adminUserIds` list, they will be able to perform any admin operation.
|
||||
|
||||
### impersonationSessionDuration
|
||||
|
||||
The duration of the impersonation session in seconds. Defaults to 1 hour.
|
||||
|
||||
@@ -290,7 +290,7 @@ describe("Admin plugin", async () => {
|
||||
},
|
||||
});
|
||||
//should reject cause the user is not admin
|
||||
expect(impersonatedUserRes.error?.status).toBe(403);
|
||||
expect(impersonatedUserRes.error?.status).toBe(401);
|
||||
const res = await client.admin.stopImpersonating(
|
||||
{},
|
||||
{
|
||||
|
||||
@@ -18,7 +18,6 @@ import { getDate } from "../../utils/date";
|
||||
import { getEndpointResponse } from "../../utils/plugin-helper";
|
||||
import { mergeSchema } from "../../db/schema";
|
||||
import { type AccessControl, type Role } from "../access";
|
||||
import { adminMiddleware } from "./call";
|
||||
import { ADMIN_ERROR_CODES } from "./error-codes";
|
||||
import { defaultStatements } from "./access";
|
||||
import { hasPermission } from "./has-permission";
|
||||
@@ -41,6 +40,15 @@ export interface AdminOptions {
|
||||
* @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
|
||||
*
|
||||
@@ -85,12 +93,32 @@ export interface AdminOptions {
|
||||
export const admin = <O extends AdminOptions>(options?: O) => {
|
||||
const opts = {
|
||||
defaultRole: "user",
|
||||
adminRoles: ["admin"],
|
||||
...options,
|
||||
};
|
||||
type DefaultStatements = typeof defaultStatements;
|
||||
type Statements = O["ac"] extends AccessControl<infer S>
|
||||
? S
|
||||
: DefaultStatements;
|
||||
|
||||
const adminMiddleware = createAuthMiddleware(async (ctx) => {
|
||||
const session = await getSessionFromCtx(ctx);
|
||||
if (
|
||||
(!session?.session || !opts.adminRoles.includes(session.user.role)) &&
|
||||
!opts.adminUserIds?.includes(session?.session?.user.id)
|
||||
) {
|
||||
throw new APIError("UNAUTHORIZED");
|
||||
}
|
||||
return {
|
||||
session,
|
||||
} as {
|
||||
session: {
|
||||
user: UserWithRole;
|
||||
session: Session;
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
id: "admin",
|
||||
init(ctx) {
|
||||
|
||||
Reference in New Issue
Block a user