fix: 对齐NapCat WebUI会话契约
This commit is contained in:
parent
06eac5a01d
commit
156ba8147e
@ -151,10 +151,12 @@ export class QqbotNapcatWebuiGatewayService {
|
||||
const target = this.toGatewayTarget(runtime);
|
||||
const gatewaySession = await this.gatewayClient.createSession({
|
||||
accountId: account.id,
|
||||
accountName: account.name,
|
||||
adminUserId: input.adminUserId,
|
||||
clientIp: input.clientIp || undefined,
|
||||
containerId: runtime.id,
|
||||
containerName: runtime.name,
|
||||
selfId: account.selfId,
|
||||
userAgent: input.userAgent || undefined,
|
||||
...target,
|
||||
});
|
||||
const webuiStatus = this.toWebuiStatus(runtime);
|
||||
@ -216,14 +218,14 @@ export class QqbotNapcatWebuiGatewayService {
|
||||
/**
|
||||
* Converts private NapCat runtime fields into the Gateway client payload.
|
||||
* @param runtime - Primary NapCat runtime containing upstream URL, port, and WebUI token.
|
||||
* @returns Internal-only Gateway target metadata.
|
||||
* @returns Internal-only Gateway target metadata without exposing the raw WebUI port separately.
|
||||
*/
|
||||
private toGatewayTarget(runtime: QqbotNapcatRuntime) {
|
||||
const targetBaseUrl = String(runtime.baseUrl || '').trim();
|
||||
const upstreamBaseUrl = String(runtime.baseUrl || '').trim();
|
||||
const webuiToken = String(runtime.webuiToken || '').trim();
|
||||
const webuiPort = Number(runtime.webuiPort);
|
||||
|
||||
if (!targetBaseUrl || !webuiToken || !Number.isFinite(webuiPort)) {
|
||||
if (!upstreamBaseUrl || !webuiToken || !Number.isFinite(webuiPort)) {
|
||||
throwVbenError('NapCat WebUI 配置不完整');
|
||||
}
|
||||
if (webuiPort <= 0) {
|
||||
@ -231,8 +233,7 @@ export class QqbotNapcatWebuiGatewayService {
|
||||
}
|
||||
|
||||
return {
|
||||
targetBaseUrl,
|
||||
webuiPort,
|
||||
upstreamBaseUrl,
|
||||
webuiToken,
|
||||
};
|
||||
}
|
||||
|
||||
@ -38,8 +38,10 @@ export class QqbotNapcatWebuiSessionResponseDto {
|
||||
@ApiProperty({ type: QqbotNapcatWebuiSessionContainerDto })
|
||||
container: QqbotNapcatWebuiSessionContainerDto;
|
||||
|
||||
@ApiProperty({ description: 'Gateway session expiry time in ISO format.' })
|
||||
expiresAt: string;
|
||||
@ApiProperty({
|
||||
description: 'Gateway session expiry timestamp in milliseconds.',
|
||||
})
|
||||
expiresAt: number;
|
||||
|
||||
@ApiProperty({ description: 'Browser-safe iframe URL served by Gateway.' })
|
||||
iframeUrl: string;
|
||||
|
||||
@ -8,17 +8,18 @@ const DEFAULT_GATEWAY_TIMEOUT_MS = 5000;
|
||||
|
||||
export type QqbotNapcatWebuiGatewayCreateSessionRequest = {
|
||||
accountId: string;
|
||||
accountName: string;
|
||||
adminUserId: string;
|
||||
clientIp?: string;
|
||||
containerId: string;
|
||||
containerName: string;
|
||||
selfId: string;
|
||||
targetBaseUrl: string;
|
||||
webuiPort: number;
|
||||
upstreamBaseUrl: string;
|
||||
userAgent?: string;
|
||||
webuiToken: string;
|
||||
};
|
||||
|
||||
export type QqbotNapcatWebuiGatewaySessionResult = {
|
||||
expiresAt: string;
|
||||
expiresAt: number;
|
||||
iframeUrl: string;
|
||||
sessionId: string;
|
||||
};
|
||||
|
||||
@ -18,6 +18,7 @@ jest.mock('axios');
|
||||
|
||||
const repoRoot = resolve(__dirname, '../../../..');
|
||||
const requestMock = axios.request as jest.Mock;
|
||||
const EXPIRES_AT_FIXTURE = 1782268000000;
|
||||
const INTERNAL_SECRET_FIXTURE = ['internal', 'secret'].join('-');
|
||||
const WEBUI_TOKEN_FIXTURE = ['webui', 'token', 'fixture'].join('-');
|
||||
|
||||
@ -87,7 +88,7 @@ describe('QqbotNapcatWebuiGatewayService', () => {
|
||||
webuiToken: WEBUI_TOKEN_FIXTURE,
|
||||
};
|
||||
const gatewayResult = {
|
||||
expiresAt: '2026-06-24T10:00:00.000Z',
|
||||
expiresAt: EXPIRES_AT_FIXTURE,
|
||||
iframeUrl: '/napcat-webui-gateway/session/sess_1/',
|
||||
sessionId: 'sess_1',
|
||||
};
|
||||
@ -132,18 +133,19 @@ describe('QqbotNapcatWebuiGatewayService', () => {
|
||||
name: 'kt-qqbot-napcat-1914728559',
|
||||
webuiStatus: 'online',
|
||||
},
|
||||
expiresAt: '2026-06-24T10:00:00.000Z',
|
||||
expiresAt: EXPIRES_AT_FIXTURE,
|
||||
iframeUrl: '/napcat-webui-gateway/session/sess_1/',
|
||||
sessionId: 'sess_1',
|
||||
});
|
||||
expect(client.createSession).toHaveBeenCalledWith({
|
||||
accountId: '1001',
|
||||
accountName: '主机器人',
|
||||
adminUserId: '3001',
|
||||
clientIp: '127.0.0.1',
|
||||
containerId: '2001',
|
||||
containerName: 'kt-qqbot-napcat-1914728559',
|
||||
selfId: '1914728559',
|
||||
targetBaseUrl: 'http://172.18.0.23:6099',
|
||||
webuiPort: 6099,
|
||||
upstreamBaseUrl: 'http://172.18.0.23:6099',
|
||||
userAgent: 'jest-agent',
|
||||
webuiToken: WEBUI_TOKEN_FIXTURE,
|
||||
});
|
||||
expect(serialized).not.toContain(WEBUI_TOKEN_FIXTURE);
|
||||
@ -258,7 +260,7 @@ describe('QqbotNapcatWebuiGatewayClient', () => {
|
||||
requestMock.mockResolvedValue({
|
||||
data: {
|
||||
data: {
|
||||
expiresAt: '2026-06-24T10:00:00.000Z',
|
||||
expiresAt: EXPIRES_AT_FIXTURE,
|
||||
iframeUrl: '/napcat-webui-gateway/session/sess_1/',
|
||||
sessionId: 'sess_1',
|
||||
},
|
||||
@ -277,20 +279,28 @@ describe('QqbotNapcatWebuiGatewayClient', () => {
|
||||
|
||||
const result = await client.createSession({
|
||||
accountId: '1001',
|
||||
accountName: '主机器人',
|
||||
adminUserId: '3001',
|
||||
clientIp: '127.0.0.1',
|
||||
containerId: '2001',
|
||||
containerName: 'kt-qqbot-napcat-1914728559',
|
||||
selfId: '1914728559',
|
||||
targetBaseUrl: 'http://172.18.0.23:6099',
|
||||
webuiPort: 6099,
|
||||
upstreamBaseUrl: 'http://172.18.0.23:6099',
|
||||
userAgent: 'jest-agent',
|
||||
webuiToken: WEBUI_TOKEN_FIXTURE,
|
||||
});
|
||||
|
||||
expect(requestMock).toHaveBeenCalledWith({
|
||||
data: expect.objectContaining({
|
||||
targetBaseUrl: 'http://172.18.0.23:6099',
|
||||
data: {
|
||||
accountId: '1001',
|
||||
adminUserId: '3001',
|
||||
clientIp: '127.0.0.1',
|
||||
containerId: '2001',
|
||||
containerName: 'kt-qqbot-napcat-1914728559',
|
||||
selfId: '1914728559',
|
||||
upstreamBaseUrl: 'http://172.18.0.23:6099',
|
||||
userAgent: 'jest-agent',
|
||||
webuiToken: WEBUI_TOKEN_FIXTURE,
|
||||
}),
|
||||
},
|
||||
headers: {
|
||||
'x-kt-gateway-secret': INTERNAL_SECRET_FIXTURE,
|
||||
},
|
||||
@ -299,7 +309,7 @@ describe('QqbotNapcatWebuiGatewayClient', () => {
|
||||
url: 'http://127.0.0.1:48086/internal/sessions',
|
||||
});
|
||||
expect(result).toEqual({
|
||||
expiresAt: '2026-06-24T10:00:00.000Z',
|
||||
expiresAt: EXPIRES_AT_FIXTURE,
|
||||
iframeUrl: '/napcat-webui-gateway/session/sess_1/',
|
||||
sessionId: 'sess_1',
|
||||
});
|
||||
@ -326,12 +336,13 @@ describe('QqbotNapcatWebuiGatewayClient', () => {
|
||||
try {
|
||||
await client.createSession({
|
||||
accountId: '1001',
|
||||
accountName: '主机器人',
|
||||
adminUserId: '3001',
|
||||
clientIp: '127.0.0.1',
|
||||
containerId: '2001',
|
||||
containerName: 'kt-qqbot-napcat-1914728559',
|
||||
selfId: '1914728559',
|
||||
targetBaseUrl: 'http://172.18.0.23:6099',
|
||||
webuiPort: 6099,
|
||||
upstreamBaseUrl: 'http://172.18.0.23:6099',
|
||||
userAgent: 'jest-agent',
|
||||
webuiToken: WEBUI_TOKEN_FIXTURE,
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user