import { app } from '@/app.ts'; import { Org } from '@/models/org.ts'; import { User } from '@/models/user.ts'; import { domain } from '@/modules/domain.ts'; const createCookie = (token: any, ctx: any) => { ctx.res.cookie('token', token.token, { maxAge: token.expireTime, domain, sameSite: 'lax', httpOnly: true, }); }; app .route({ path: 'user', key: 'me', middleware: ['auth'], }) .define(async (ctx) => { const tokenUser = ctx.state?.tokenUser || {}; const { id } = tokenUser; const user = await User.findByPk(id, { logging: false, }); if (!user) { ctx.throw(500, 'user not found'); } user.setTokenUser(tokenUser); ctx.body = await user.getInfo(); }) .addTo(app); app .route({ path: 'user', key: 'login', }) .define(async (ctx) => { const { username, email, password, loginType = 'default' } = ctx.query; if (!username && !email) { ctx.throw(400, 'username or email is required'); } let user: User | null = null; if (username) { user = await User.findOne({ where: { username }, logging: false }); } if (!user && email) { user = await User.findOne({ where: { email } }); } if (!user) { ctx.throw(500, 'Login Failed'); } if (!user.checkPassword(password)) { ctx.throw(500, 'Password error'); } const token = await user.createToken(null, loginType); createCookie(token, ctx); ctx.body = token; }) .addTo(app); app .route({ path: 'user', key: 'logout', }) .define(async (ctx) => { ctx.res.cookie('token', '', { maxAge: 0, domain: `${domain}`, sameSite: 'lax', httpOnly: true, }); }) .addTo(app); app .route('user', 'auth') .define(async (ctx) => { const { checkToken: token } = ctx.query; try { const result = await User.verifyToken(token); ctx.body = result || {}; } catch (e) { ctx.throw(401, 'Token InValid '); } }) .addTo(app); app .route('user', 'updateSelf', { middleware: ['auth'], }) .define(async (ctx) => { const { username, password, description, avatar, email } = ctx.query.data || {}; const tokenUser = ctx.state?.tokenUser || {}; const { id } = tokenUser; const user = await User.findByPk(id); if (!user) { ctx.throw(500, 'user not found'); } user.setTokenUser(tokenUser); if (username) { user.username = username; } if (password) { user.createPassword(password); } if (description) { user.description = description; } if (avatar) { user.avatar = avatar; } if (email) { user.email = email; } await user.save(); ctx.body = await user.getInfo(); }) .addTo(app); app .route({ path: 'user', key: 'switchOrg', middleware: ['auth'], }) .define(async (ctx) => { const tokenUser = ctx.state.tokenUser; const { username, type = 'org', loginType } = ctx.query.data || {}; if (!username && type === 'org') { ctx.throw('username is required'); } if (tokenUser.username === username) { // 自己刷新自己的token const user = await User.findByPk(tokenUser.id); if (!user) { ctx.throw('user not found'); } if (user.type === 'user') { const token = await user.createToken(null, loginType); createCookie(token, ctx); ctx.body = token; return; } else if (user.type === 'org' && tokenUser.uid) { const token = await user.createToken(tokenUser.uid, loginType); createCookie(token, ctx); ctx.body = token; return; } } let me: User; if (tokenUser.uid) { me = await User.findByPk(tokenUser.uid); } else { me = await User.findByPk(tokenUser.id); // 真实用户 } if (!me || me.type === 'org') { console.log('switch Error ', me.username, me.type); ctx.throw('Permission denied'); } if (type === 'user') { const token = await me.createToken(null, loginType); createCookie(token, ctx); ctx.body = token; return; } const orgUser = await User.findOne({ where: { username } }); if (!orgUser) { ctx.throw('org user not found'); } if (orgUser.type === 'user') { // 想转换的type===org, 但实际上这个用户名是一个用户, 比如org调用switchOrg root const token = await orgUser.createToken(null, loginType); createCookie(token, ctx); ctx.body = token; return; } const user = await Org.findOne({ where: { username } }); const users = user.users; const index = users.findIndex((u) => u.uid === me.id); if (index === -1) { ctx.throw('Permission denied'); } const token = await orgUser.createToken(me.id, loginType); createCookie(token, ctx); ctx.body = token; }) .addTo(app);