Add password login support to web UI and backend

Implement password-based QQ login across the stack: add a PasswordLogin React component, integrate it into the QQ login page, and add a frontend controller method to call a new /QQLogin/PasswordLogin API. On the backend, add QQPasswordLoginHandler, router entry, and WebUiDataRuntime hooks (setPasswordLoginCall / requestPasswordLogin) plus a default handler. Register a password login callback in the shell (base.ts) that calls the kernel login service, handles common error cases and falls back to QR code when needed. Update types to include onPasswordLoginRequested and adjust NodeIKernelLoginService method signatures (including passwordLogin return type changed to Promise<QuickLoginResult>) and minor formatting fixes.
This commit is contained in:
手瓜一十雪
2026-02-02 19:48:31 +08:00
parent 0fd1a32293
commit 168447dcbc
9 changed files with 269 additions and 20 deletions

View File

@@ -108,3 +108,29 @@ export const QQRefreshQRcodeHandler: RequestHandler = async (_, res) => {
await WebUiDataRuntime.refreshQRCode();
return sendSuccess(res, null);
};
// 密码登录
export const QQPasswordLoginHandler: RequestHandler = async (req, res) => {
// 获取QQ号和密码MD5
const { uin, passwordMd5 } = req.body;
// 判断是否已经登录
const isLogin = WebUiDataRuntime.getQQLoginStatus();
if (isLogin) {
return sendError(res, 'QQ Is Logined');
}
// 判断QQ号是否为空
if (isEmpty(uin)) {
return sendError(res, 'uin is empty');
}
// 判断密码MD5是否为空
if (isEmpty(passwordMd5)) {
return sendError(res, 'passwordMd5 is empty');
}
// 执行密码登录
const { result, message } = await WebUiDataRuntime.requestPasswordLogin(uin, passwordMd5);
if (!result) {
return sendError(res, message);
}
return sendSuccess(res, null);
};

View File

@@ -33,6 +33,9 @@ const LoginRuntime: LoginRuntimeType = {
onQuickLoginRequested: async () => {
return { result: false, message: '' };
},
onPasswordLoginRequested: async () => {
return { result: false, message: '密码登录功能未初始化' };
},
onRestartProcessRequested: async () => {
return { result: false, message: '重启功能未初始化' };
},
@@ -136,6 +139,14 @@ export const WebUiDataRuntime = {
return LoginRuntime.NapCatHelper.onQuickLoginRequested(uin);
} as LoginRuntimeType['NapCatHelper']['onQuickLoginRequested'],
setPasswordLoginCall (func: LoginRuntimeType['NapCatHelper']['onPasswordLoginRequested']): void {
LoginRuntime.NapCatHelper.onPasswordLoginRequested = func;
},
requestPasswordLogin: function (uin: string, passwordMd5: string) {
return LoginRuntime.NapCatHelper.onPasswordLoginRequested(uin, passwordMd5);
} as LoginRuntimeType['NapCatHelper']['onPasswordLoginRequested'],
setOnOB11ConfigChanged (func: LoginRuntimeType['NapCatHelper']['onOB11ConfigChanged']): void {
LoginRuntime.NapCatHelper.onOB11ConfigChanged = func;
},

View File

@@ -10,6 +10,7 @@ import {
getAutoLoginAccountHandler,
setAutoLoginAccountHandler,
QQRefreshQRcodeHandler,
QQPasswordLoginHandler,
} from '@/napcat-webui-backend/src/api/QQLogin';
const router: Router = Router();
@@ -31,5 +32,7 @@ router.post('/GetQuickLoginQQ', getAutoLoginAccountHandler);
router.post('/SetQuickLoginQQ', setAutoLoginAccountHandler);
// router:刷新QQ登录二维码
router.post('/RefreshQRcode', QQRefreshQRcodeHandler);
// router:密码登录
router.post('/PasswordLogin', QQPasswordLoginHandler);
export { router as QQLoginRouter };

View File

@@ -56,6 +56,7 @@ export interface LoginRuntimeType {
OneBotContext: any | null; // OneBot 上下文,用于调试功能
NapCatHelper: {
onQuickLoginRequested: (uin: string) => Promise<{ result: boolean; message: string; }>;
onPasswordLoginRequested: (uin: string, passwordMd5: string) => Promise<{ result: boolean; message: string; }>;
onOB11ConfigChanged: (ob11: OneBotConfig) => Promise<void>;
onRestartProcessRequested: () => Promise<{ result: boolean; message: string; }>;
QQLoginList: string[];