import { app } from '@/app.ts'; import { User } from '@/models/user.ts'; import { nanoid } from 'nanoid'; import { CustomError } from '@kevisual/router'; import { backupUserA, deleteUser, mvUserAToUserB } from '@/routes/file/index.ts'; import { AppModel } from '@/routes/app-manager/index.ts'; // import { mvAppFromUserAToUserB } from '@/routes/app-manager/admin/mv-user-app.ts'; export const checkUsername = (username: string) => { if (username.length > 30) { throw new CustomError(400, 'Username cannot be too long'); } if (!/^[a-zA-Z0-9_@]+$/.test(username)) { throw new CustomError(400, 'Username cannot contain special characters'); } if (username.includes(' ')) { throw new CustomError(400, 'Username cannot contain spaces'); } }; export const checkUsernameShort = (username: string) => { if (username.length < 3) { throw new CustomError(400, 'Username cannot be too short'); } }; app .route({ path: 'user', key: 'changeName', middleware: ['auth-admin'], }) .define(async (ctx) => { const { id, newName } = ctx.query.data || {}; const user = await User.findByPk(id); if (!user) { ctx.throw(404, 'User not found'); } const oldName = user.username; checkUsername(newName); const findUserByUsername = await User.findOne({ where: { username: newName } }); if (findUserByUsername) { ctx.throw(400, 'Username already exists'); } user.username = newName; try { await user.save(); // 迁移文件数据 await backupUserA(oldName, user.id); // 备份文件数据 await mvUserAToUserB(oldName, newName, true); // 迁移文件数据 // await mvAppFromUserAToUserB(oldName, newName); // 迁移应用数据 if (['org', 'user'].includes(user.type)) { const type = user.type === 'org' ? 'org' : 'user'; await User.clearUserToken(user.id, type); // 清除旧token } await AppModel.moveToNewUser(oldName, newName); // 更新用户数据 } catch (error) { console.error('迁移文件数据失败', error); ctx.throw(500, 'Failed to change username'); } ctx.body = user; }) .addTo(app); app .route({ path: 'user', key: 'checkUserExist', middleware: ['auth'], }) .define(async (ctx) => { const { username } = ctx.query.data || {}; if (!username) { ctx.throw(400, 'Username is required'); } checkUsername(username); const user = await User.findOne({ where: { username } }); ctx.body = { id: user?.id, username: user?.username, }; }) .addTo(app); app .route({ path: 'user', key: 'resetPassword', middleware: ['auth-admin'], }) .define(async (ctx) => { const { id, password } = ctx.query.data || {}; const user = await User.findByPk(id); if (!user) { ctx.throw(404, 'User not found'); } let pwd = password || nanoid(6); user.createPassword(pwd); await user.save(); ctx.body = { id: user.id, username: user.username, password: !password ? pwd : undefined, }; }) .addTo(app); app .route({ path: 'user', key: 'createNewUser', middleware: ['auth-admin'], }) .define(async (ctx) => { const { username, password, description } = ctx.query.data || {}; if (!username) { ctx.throw(400, 'Username is required'); } checkUsername(username); const findUserByUsername = await User.findOne({ where: { username } }); if (findUserByUsername) { ctx.throw(400, 'Username already exists'); } let pwd = password || nanoid(6); const user = await User.createUser(username, pwd, description); ctx.body = { id: user.id, username: user.username, description: user.description, password: pwd, }; }) .addTo(app); app .route({ path: 'user', key: 'deleteUser', middleware: ['auth-admin'], }) .define(async (ctx) => { const { id } = ctx.query.data || {}; const user = await User.findByPk(id); if (!user) { ctx.throw(404, 'User not found'); } await user.destroy(); backupUserA(user.username, user.id); deleteUser(user.username); // TODO: EXPIRE 删除token ctx.body = { id: user.id, username: user.username, message: 'User deleted successfully', }; }) .addTo(app);