112 lines
3.2 KiB
TypeScript
112 lines
3.2 KiB
TypeScript
import type { CollectionConfig } from 'payload'
|
||
|
||
export const Users: CollectionConfig = {
|
||
slug: 'users',
|
||
admin: {
|
||
useAsTitle: 'email',
|
||
},
|
||
auth: true,
|
||
fields: [
|
||
// Email added by default
|
||
{
|
||
name: 'roles',
|
||
type: 'select',
|
||
hasMany: true,
|
||
options: ['admin', 'editor', 'user'],
|
||
defaultValue: ['user'],
|
||
required: true,
|
||
saveToJWT: true, // Include in JWT for fast access checks
|
||
access: {
|
||
update: ({ req: { user } }) => {
|
||
// Only admins can update roles
|
||
if (!user) return false
|
||
return user.roles?.includes('admin') || false
|
||
},
|
||
},
|
||
},
|
||
],
|
||
hooks: {
|
||
beforeChange: [
|
||
async ({ data, req, operation }) => {
|
||
// 如果是创建操作,检查是否为第一个用户
|
||
if (operation === 'create') {
|
||
const { totalDocs } = await req.payload.count({
|
||
collection: 'users',
|
||
})
|
||
|
||
// 如果这是第一个用户,自动设置为 admin
|
||
if (totalDocs === 0) {
|
||
data.roles = ['admin']
|
||
console.log('🎉 第一个用户注册,自动设置为管理员')
|
||
}
|
||
}
|
||
|
||
// 如果是更新操作,检查是否为唯一用户且 roles 为空
|
||
if (operation === 'update') {
|
||
const { totalDocs } = await req.payload.count({
|
||
collection: 'users',
|
||
})
|
||
|
||
// 如果只有一个用户且 roles 为空或只有 user,自动升级为 admin
|
||
if (
|
||
totalDocs === 1 &&
|
||
(!data.roles ||
|
||
data.roles.length === 0 ||
|
||
(data.roles.length === 1 && data.roles[0] === 'user'))
|
||
) {
|
||
data.roles = ['admin']
|
||
console.log('🔧 当前是唯一用户,自动升级为管理员')
|
||
}
|
||
}
|
||
|
||
return data
|
||
},
|
||
],
|
||
afterRead: [
|
||
async ({ doc, req, context }) => {
|
||
// 跳过已标记为处理过的请求
|
||
if (context?.skipAutoAdmin) return doc
|
||
|
||
// 检查是否为唯一用户且 roles 为空或不正确
|
||
if (
|
||
!doc.roles ||
|
||
doc.roles.length === 0 ||
|
||
(doc.roles.length === 1 && doc.roles[0] === 'user')
|
||
) {
|
||
const { totalDocs } = await req.payload.count({
|
||
collection: 'users',
|
||
})
|
||
|
||
// 如果只有一个用户,自动更新为 admin
|
||
if (totalDocs === 1) {
|
||
console.log('🔄 检测到唯一用户权限异常,正在修复...')
|
||
|
||
try {
|
||
// 使用 overrideAccess 绕过权限检查,标记 context 避免循环
|
||
await req.payload.update({
|
||
collection: 'users',
|
||
id: doc.id,
|
||
data: {
|
||
roles: ['admin'],
|
||
},
|
||
context: {
|
||
skipAutoAdmin: true,
|
||
},
|
||
overrideAccess: true,
|
||
})
|
||
|
||
// 更新当前文档的 roles
|
||
doc.roles = ['admin']
|
||
console.log('✅ 唯一用户权限已修复为管理员')
|
||
} catch (error) {
|
||
console.error('❌ 更新用户权限失败:', error)
|
||
}
|
||
}
|
||
}
|
||
|
||
return doc
|
||
},
|
||
],
|
||
},
|
||
}
|