feat: add login for plugin

This commit is contained in:
2025-03-23 16:48:19 +08:00
parent 74a484718a
commit cb490470c1
18 changed files with 1079 additions and 369 deletions

View File

@@ -1,30 +1,72 @@
import { app } from '@/app.ts';
import { User } from '@/models/user.ts';
import MD5 from 'crypto-js/md5.js';
import { authCan } from '@kevisual/code-center-module/models';
import jsonwebtoken from 'jsonwebtoken';
// const tokenData: Record<string, string> = {};
import { redis } from '@/app.ts';
import { createCookie } from './me.ts';
import { createCookie, clearCookie } from './me.ts';
app
.route({
path: 'user',
key: 'webLogin',
middleware: ['auth'],
middleware: [authCan],
})
.define(async (ctx) => {
const tokenUser = ctx.state.tokenUser;
const token = ctx.query.token;
const { loginToken, sign, randomId } = ctx.query || {};
const setErrorLoginTokenRedis = async (loginToken: string) => {
await redis.set(loginToken, JSON.stringify({}), 'EX', 2 * 60); // 2分钟
};
if (!tokenUser) {
if (token) {
console.log('web-login, token', ' run clearCookie', token, tokenUser);
// clearCookie(ctx);
} else {
// const message = 'token is expired, please login in web page. ';
}
try {
ctx.res.setHeader('Content-Type', 'text/html');
const createRedirectHtml = () => {
const reqUrl = ctx.req.url;
return `
<html lang="zh-CN">
<body>
<h1>login with web page</h1>
<a href="${reqUrl}">${reqUrl}</a>
<script>
const redirect = new URL('${reqUrl}', window.location.origin);
const encodeRedirect = encodeURIComponent(redirect.toString());
const toPage = new URL('/user/login/?user-check=true&redirect='+encodeRedirect, window.location.origin);
setTimeout(() => {
window.location.href = toPage.toString();
}, 1000);
</script>
</body>
</html>
`;
};
ctx.res.end(createRedirectHtml());
} catch (e) {
await setErrorLoginTokenRedis(loginToken);
ctx.throw(400, 'token is expired and redirect error');
}
return;
}
if (!loginToken) {
await setErrorLoginTokenRedis(loginToken);
ctx.throw(400, 'loginToken is required');
}
if (!sign) {
await setErrorLoginTokenRedis(loginToken);
ctx.throw(400, 'sign is required');
}
if (!randomId) {
await setErrorLoginTokenRedis(loginToken);
ctx.throw(400, 'randomId is required');
}
const tokenSecret = 'xiao' + randomId;
@@ -32,16 +74,19 @@ app
try {
payload = jsonwebtoken.verify(loginToken, tokenSecret);
} catch (e) {
await setErrorLoginTokenRedis(loginToken);
ctx.throw(400, 'loginToken error');
}
const { timestamp } = payload;
const checkSign = MD5(`${tokenSecret}${timestamp}`).toString();
if (sign !== checkSign) {
await setErrorLoginTokenRedis(loginToken);
ctx.throw(400, 'sign error');
}
const user = await User.findByPk(tokenUser.id);
if (!user) {
await setErrorLoginTokenRedis(loginToken);
ctx.throw(400, 'user not found');
}
const data = await user.createToken(null, 'plugin', { loginWith: 'cli' });
@@ -63,11 +108,16 @@ app
// const data = tokenData[loginToken];
const data = await redis.get(loginToken);
if (data) {
ctx.body = JSON.parse(data);
await redis.expire(loginToken, 3600);
const token = JSON.parse(data);
if (token.accessToken) {
ctx.body = token;
createCookie(token, ctx);
} else {
ctx.throw(500, 'Checked error Failed, login failed, please login again');
}
await redis.expire(loginToken, 2 * 60); // 2分钟
} else {
ctx.throw(400, 'Checked Failed');
}
createCookie(data, ctx);
})
.addTo(app);