286 lines
6.8 KiB
TypeScript
286 lines
6.8 KiB
TypeScript
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);
|