mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-18 13:23:33 +08:00
fix: keep H5 LAN links on the active server port
H5 access can preserve a manually selected private LAN host, but the desktop sidecar binds a fresh dynamic port on restart. Refresh plain HTTP private-LAN URLs to the current auto-discovered port while leaving reverse proxy URLs intact. Constraint: Desktop sidecar ports are dynamic across app launches. Rejected: Preserve the complete private-LAN URL unchanged | this keeps stale ports like 5179 in QR links after restart. Confidence: high Scope-risk: narrow Directive: Do not treat plain private-LAN H5 URLs as reverse proxy URLs unless they carry a custom scheme or path. Tested: bun test src/server/__tests__/h5-access-service.test.ts Tested: bun test src/server/__tests__/h5-access-api.test.ts src/server/__tests__/h5-access-auth.test.ts src/server/__tests__/h5-access-policy.test.ts Tested: bun run check:server Tested: manual smoke with stored :5179 returning the active :45679 publicBaseUrl Not-tested: Real phone scan against a packaged desktop build after reinstall.
This commit is contained in:
parent
77552375e9
commit
248a3b4294
@ -101,7 +101,7 @@ describe('H5AccessService', () => {
|
||||
expect(result.settings.publicBaseUrl).toBe('https://chat.example.com/app')
|
||||
})
|
||||
|
||||
test('auto LAN mode fills blank or loopback URLs but preserves manual LAN URLs', () => {
|
||||
test('auto LAN mode fills blank or loopback URLs and refreshes manual LAN ports', () => {
|
||||
expect(resolveEffectiveH5PublicBaseUrl({
|
||||
enabled: true,
|
||||
storedPublicBaseUrl: null,
|
||||
@ -121,7 +121,7 @@ describe('H5AccessService', () => {
|
||||
storedPublicBaseUrl: 'http://192.168.1.100:54064',
|
||||
configuredPublicBaseUrl: null,
|
||||
autoPublicBaseUrl: 'http://172.20.16.1:39876',
|
||||
})).toBe('http://192.168.1.100:54064')
|
||||
})).toBe('http://192.168.1.100:39876')
|
||||
|
||||
expect(resolveEffectiveH5PublicBaseUrl({
|
||||
enabled: true,
|
||||
@ -131,6 +131,22 @@ describe('H5AccessService', () => {
|
||||
})).toBe('https://chat.example.com/app')
|
||||
})
|
||||
|
||||
test('auto LAN mode keeps full reverse proxy URLs intact', () => {
|
||||
expect(resolveEffectiveH5PublicBaseUrl({
|
||||
enabled: true,
|
||||
storedPublicBaseUrl: 'https://192.168.1.100:8443',
|
||||
configuredPublicBaseUrl: null,
|
||||
autoPublicBaseUrl: 'http://192.168.1.100:39876',
|
||||
})).toBe('https://192.168.1.100:8443')
|
||||
|
||||
expect(resolveEffectiveH5PublicBaseUrl({
|
||||
enabled: true,
|
||||
storedPublicBaseUrl: 'http://192.168.1.100:8080/h5',
|
||||
configuredPublicBaseUrl: null,
|
||||
autoPublicBaseUrl: 'http://192.168.1.100:39876',
|
||||
})).toBe('http://192.168.1.100:8080/h5')
|
||||
})
|
||||
|
||||
test('auto LAN detection prefers physical adapters over WSL and Docker virtual adapters', () => {
|
||||
expect(findPrivateLanAddress({
|
||||
'vEthernet (WSL)': [{
|
||||
|
||||
@ -179,6 +179,11 @@ export function resolveEffectiveH5PublicBaseUrl({
|
||||
return autoPublicBaseUrl
|
||||
}
|
||||
|
||||
const refreshedLanUrl = refreshLanPublicBaseUrlPort(storedPublicBaseUrl, autoPublicBaseUrl)
|
||||
if (refreshedLanUrl) {
|
||||
return refreshedLanUrl
|
||||
}
|
||||
|
||||
return storedPublicBaseUrl
|
||||
}
|
||||
|
||||
@ -203,6 +208,27 @@ function isLocalHost(hostname: string): boolean {
|
||||
hostname === '::'
|
||||
}
|
||||
|
||||
function refreshLanPublicBaseUrlPort(storedPublicBaseUrl: string, autoPublicBaseUrl: string): string | null {
|
||||
try {
|
||||
const stored = new URL(storedPublicBaseUrl)
|
||||
const auto = new URL(autoPublicBaseUrl)
|
||||
const storedPath = stored.pathname.replace(/\/+$/, '')
|
||||
|
||||
if (
|
||||
stored.protocol !== 'http:' ||
|
||||
storedPath !== '' ||
|
||||
!isPrivateIPv4(stored.hostname) ||
|
||||
!auto.port
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
return `${stored.protocol}//${stored.hostname}:${auto.port}`
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
type NetworkInterfaces = ReturnType<typeof os.networkInterfaces>
|
||||
|
||||
const PHYSICAL_INTERFACE_RE = /\b(wi-?fi|wlan|wireless|ethernet|lan|en\d+|eth\d+)\b/i
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user