feat: login by command by web
This commit is contained in:
94
src/module/login/login-by-web.ts
Normal file
94
src/module/login/login-by-web.ts
Normal 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();
|
||||
Reference in New Issue
Block a user