import { app } from '@/app.ts'; import { Org } from '@/models/org.ts'; import { User } from '@/models/user.ts'; import { domain } from '@/modules/domain.ts'; /** * 当配置了domain后,创建cookie,当get请求地址的时候,会自动带上cookie * @param token * @param ctx * @returns */ export const createCookie = (token: any, ctx: any) => { if (!domain) { return; } if (ctx.res.cookie) { ctx.res.cookie('token', token.token, { maxAge: 7 * 24 * 60 * 60 * 1000, // 过期时间, 设置7天 domain, sameSite: 'lax', httpOnly: true, }); } }; const clearCookie = (ctx: any) => { if (!domain) { return; } ctx.res.cookie('token', '', { maxAge: 0, 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', middleware: ['auth-can'], }) .define(async (ctx) => { const oldToken = ctx.query.token; const tokenUser = ctx.state?.tokenUser || {}; 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 (tokenUser.id === user.id) { // 自己刷新自己的token const token = await User.oauth.resetToken(oldToken, { ...tokenUser.oauthExpand, }); createCookie(token, ctx); ctx.body = token; return; } if (!user.checkPassword(password)) { ctx.throw(500, 'Password error'); } user.expireOrgs(); const token = await user.createToken(null, loginType); createCookie(token, ctx); ctx.body = token; }) .addTo(app); app .route({ path: 'user', key: 'logout', }) .define(async (ctx) => { const { tokens = [] } = ctx.query?.data || {}; clearCookie(ctx); for (const token of tokens) { await User.oauth.delToken(token); } ctx.body = { code: 200, message: 'Logout Success', }; }) .addTo(app); app .route({ path: 'user', key: 'auth', middleware: ['auth-can'], }) .define(async (ctx) => { const { checkToken: token } = ctx.query; try { const result = await User.verifyToken(token); if (result) { delete result.oauthExpand; } ctx.body = result || {}; } catch (e) { ctx.throw(401, 'Token InValid '); } }) .addTo(app); app .route({ path: 'user', key: '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: 'switchCheck', middleware: ['auth'], }) .define(async (ctx) => { const token = ctx.query.token; const { username, accessToken } = ctx.query.data || {}; if (accessToken && username) { const accessUser = await User.verifyToken(accessToken); const refreshToken = accessUser.oauthExpand?.refreshToken; if (refreshToken) { const result = await User.oauth.refreshToken(refreshToken); createCookie(result, ctx); ctx.body = result; return; } else if (accessUser) { await User.oauth.delToken(accessToken); const result = await User.oauth.generateToken(accessUser, { ...accessUser.oauthExpand, hasRefreshToken: true, }); createCookie(result, ctx); ctx.body = result; return; } } else { const result = await ctx.call( { path: 'user', key: 'switchOrg', payload: { data: { username, }, token, }, }, { res: ctx.res, req: ctx.req, }, ); if (result.code === 200) { ctx.body = result.body; } else { ctx.throw(result.code, result.message); } } }) .addTo(app); app .route({ path: 'user', key: 'switchOrg', middleware: ['auth'], }) .define(async (ctx) => { const tokenUser = ctx.state.tokenUser; const token = ctx.query.token; const tokenUsername = tokenUser.username; const userId = tokenUser.userId; let { username } = ctx.query.data || {}; const user = await User.findByPk(userId); if (!user) { ctx.throw('user not found'); } if (!username) { username = user.username; } const orgs = await user.getOrgs(); const orgsList = [tokenUser.username, user.username, , ...orgs]; if (orgsList.includes(username)) { if (tokenUsername === username) { const result = await User.oauth.resetToken(token); createCookie(result, ctx); await User.oauth.delToken(token); ctx.body = result; } else { const user = await User.findOne({ where: { username } }); const result = await user.createToken(userId, 'default'); createCookie(result, ctx); ctx.body = result; } } else { ctx.throw(403, 'Permission denied'); } }) .addTo(app); app .route({ path: 'user', key: 'refreshToken', }) .define(async (ctx) => { const { refreshToken } = ctx.query.data || {}; try { if (!refreshToken) { ctx.throw(400, 'Refresh Token is required'); } const result = await User.oauth.refreshToken(refreshToken); if (result) { console.log('refreshToken result', result); createCookie(result, ctx); ctx.body = result; } else { ctx.throw(500, 'Refresh Token Failed, please login again'); } } catch (e) { console.log('refreshToken error', e); ctx.throw(400, 'Refresh Token Failed'); } }) .addTo(app);