feat: basic admin interface
This commit is contained in:
+29
-4
@@ -7,15 +7,20 @@ import { admin } from 'better-auth/plugins/admin';
|
||||
import { defaultStatements } from 'better-auth/plugins/admin/access';
|
||||
import { twoFactor } from 'better-auth/plugins/two-factor';
|
||||
import * as schema from '../drizzle/schema';
|
||||
import { getRegistrationMode } from '../server/utils/instance';
|
||||
|
||||
const MIN_PASSWORD_LENGTH = 8;
|
||||
|
||||
const accessControl = createAccessControl(defaultStatements);
|
||||
|
||||
// Admins manage accounts, not content. Signing in as someone else and setting
|
||||
// another user's password or email are left out on purpose: the first would
|
||||
// show their chats, the others would lock them out of their encrypted API keys.
|
||||
// Deleting is left out too, because Better Auth would only remove the account
|
||||
// and leave its agents, topics and files behind. /api/admin/users does that.
|
||||
const roles = {
|
||||
admin: accessControl.newRole({
|
||||
user: ['create', 'list', 'set-role', 'ban', 'delete', 'get', 'update'],
|
||||
user: ['create', 'list', 'set-role', 'ban', 'get', 'update'],
|
||||
session: ['list', 'revoke', 'delete'],
|
||||
}),
|
||||
user: accessControl.newRole({
|
||||
@@ -44,10 +49,30 @@ export const auth = betterAuth({
|
||||
trustedOrigins: [process.env.NUXT_PUBLIC_URL ?? 'http://localhost:3000'],
|
||||
|
||||
hooks: {
|
||||
// The admin endpoints already stop admins from removing or disabling
|
||||
// themselves. Giving up their own admin role is the one way left to
|
||||
// end up with an instance nobody can manage, so that is refused too.
|
||||
before: createAuthMiddleware(async (ctx) => {
|
||||
// Who may register is an instance setting admins change at runtime.
|
||||
// Invite links do not exist yet, so only open instances take sign ups.
|
||||
if (ctx.path === '/sign-up/email' && await getRegistrationMode() !== 'open') {
|
||||
throw new APIError('FORBIDDEN', {
|
||||
message: 'Registration is closed on this instance',
|
||||
code: 'REGISTRATION_CLOSED',
|
||||
});
|
||||
}
|
||||
|
||||
// creating a user as an admin skips the sign up password rules
|
||||
if (ctx.path === '/admin/create-user') {
|
||||
const password = ctx.body?.password;
|
||||
if (typeof password !== 'string' || password.length < MIN_PASSWORD_LENGTH) {
|
||||
throw new APIError('BAD_REQUEST', {
|
||||
message: 'Password is too short',
|
||||
code: 'PASSWORD_TOO_SHORT',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// The admin endpoints already stop admins from removing or disabling
|
||||
// themselves. Giving up their own admin role is the one way left to
|
||||
// end up with an instance nobody can manage, so that is refused too.
|
||||
if (ctx.path !== '/admin/set-role' && ctx.path !== '/admin/update-user') return;
|
||||
|
||||
const role = ctx.path === '/admin/set-role' ? ctx.body?.role : ctx.body?.data?.role;
|
||||
|
||||
Reference in New Issue
Block a user