feat(desktop): open read-only TurkServis combo details in browser pane

This commit is contained in:
yilsem committed 2026-09-07 21:46:57 +03:00
1 parent ff2eb47302
commit 3332458708
16 files changed
+110 -4

No files matched your search

@@ -0,0 +1,25 @@
import { describe, expect, it } from 'vitest'
import { turkservisComboDetailsUrl } from './turkservis-combo-details'
describe('TurkServis read-only details link', () => {
it('preserves the exact model and drops API query parameters', () => {
const result = turkservisComboDetailsUrl('https://ai.turkservis.online/v1?key=private', '9router-Team & A')!
expect(new URL(result).searchParams.get('model')).toBe('9router-Team & A')
expect(new URL(result).origin).toBe('https://turkservis.online')
expect(result).not.toContain('private')
})
it.each([undefined, '', 'invalid', 'http://ai.turkservis.online/v1',
'https://ai.turkservis.online.evil.test/v1', 'https://other.test/v1',
'https://user:secret@ai.turkservis.online/v1', 'https://ai.turkservis.online:9090/v1'
])('does not offer details for an unrelated or unsafe endpoint: %s', apiUrl => {
expect(turkservisComboDetailsUrl(apiUrl, 'Team')).toBeNull()
})
it('rejects missing and oversized model identities', () => {
expect(turkservisComboDetailsUrl('https://turkservis.online/v1', '')).toBeNull()
expect(turkservisComboDetailsUrl('https://turkservis.online/v1', 'x'.repeat(129))).toBeNull()
})
})
@@ -0,0 +1,21 @@
/** Details use the member portal's own login; API credentials never enter a URL. */
export function turkservisComboDetailsUrl(apiUrl: string | undefined, model: string): string | null {
if (!apiUrl || !model || model.length > 128) {return null}
try {
const endpoint = new URL(apiUrl)
if (
endpoint.protocol !== 'https:' || endpoint.username || endpoint.password || endpoint.port ||
!['ai.turkservis.online', 'turkservis.online'].includes(endpoint.hostname)
) {return null}
const details = new URL('https://turkservis.online/router')
details.searchParams.set('model', model)
return details.href
} catch {
return null
}
}