feat: login by command by web

This commit is contained in:
2025-02-25 20:04:24 +08:00
parent 02a1f51d63
commit 26c6248d10
8 changed files with 644 additions and 210 deletions

View File

@@ -0,0 +1,94 @@
import MD5 from 'crypto-js/md5.js';
import { getBaseURL, query } from '../query.ts';
import { chalk } from '../chalk.ts';
import jsonwebtoken from 'jsonwebtoken';
import { BaseLoad } from '@kevisual/load';
import { getConfig, writeConfig } from '../get-config.ts';
export const saveToken = async (token: string) => {
const config = await getConfig();
writeConfig({
...config,
token,
});
};
type LoginWithWebOptions = {};
export const loginWithWeb = async (opts?: LoginWithWebOptions) => {
const baseURL = getBaseURL();
const randomId = Math.random().toString(36).substring(2, 15);
const timestamp = Date.now();
const tokenSecret = 'xiao' + randomId;
const sign = MD5(`${tokenSecret}${timestamp}`).toString();
const token = jsonwebtoken.sign({ randomId, timestamp, sign }, tokenSecret, {
// 10分钟过期
expiresIn: 60 * 10, // 10分钟
});
const config = await getConfig();
const url = `${baseURL}/api/router?path=user&key=webLogin&p&loginToken=${token}&sign=${sign}&randomId=${randomId}`;
console.log(chalk.blue(url));
return {
url,
token,
tokenSecret,
};
};
type PollLoginOptions = {
tokenSecret: string;
};
export const pollLoginStatus = async (token: string, opts: PollLoginOptions) => {
const load = new BaseLoad();
load.load(
async () => {
const res = await query.post({
path: 'user',
key: 'checkLoginStatus',
loginToken: token,
});
return res;
},
{
key: 'check-login-status',
isReRun: true,
checkSuccess: (data) => {
return data?.code === 200;
},
},
);
const res = await load.hasLoaded('check-login-status', {
timeout: 60 * 3 * 1000, // 5分钟超时
});
if (res.code === 200 && res.data?.code === 200) {
const data = res.data?.data;
try {
const payload = jsonwebtoken.verify(data, opts.tokenSecret) as UserPayload;
type UserPayload = {
userToken: {
token: string;
expireTime: number;
};
user: {
id: string;
username: string;
};
};
const userToken = payload.userToken;
// console.log('token:\n\n', userToken);
console.log(chalk.green('登录成功', payload?.user?.username));
await saveToken(userToken.token);
return;
} catch (error) {
console.log(chalk.red('登录失败'), error);
}
}
console.log(chalk.red('登录失败'), res);
};
export const loginInCommand = async () => {
const { url, token, tokenSecret } = await loginWithWeb();
await pollLoginStatus(token, { tokenSecret });
return url;
};
// loginInCommand();