286 lines
6.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);