feat(web,ui): per-provider git forge API base URL and detection URLs
Configure a default API base URL per git provider (github/gitlab/gitea) in settings.json gitProviders, with GitHub Enterprise support (Octokit baseUrl + device-flow web origin derived from the API base), and replace the client-side custom-domains list with server-persisted detection URL chips (SSH/HTTPS forms normalized to hosts). The configured API base host auto-counts as a detection host. Settings round-trip through the existing /api/config/settings sanitizer; the UI store hydrates from server settings with a one-time localStorage migration.
This commit is contained in:
@@ -465,6 +465,46 @@ describe('settings helpers', () => {
|
||||
expect(sanitized.favoriteModels).toEqual(payload.favoriteModels);
|
||||
expect(sanitized.recentModels).toEqual(payload.recentModels);
|
||||
});
|
||||
|
||||
it('round-trips a valid gitProviders payload through sanitizeSettingsUpdate', () => {
|
||||
const helpers = createTestHelpersWithRealSanitizers();
|
||||
const payload = {
|
||||
gitProviders: {
|
||||
github: { apiBaseUrl: 'https://github.example.com/api/v3', detectUrls: ['github.example.com'] },
|
||||
gitlab: { apiBaseUrl: 'gitlab.example.com', detectUrls: [] },
|
||||
gitea: { apiBaseUrl: '', detectUrls: ['gitea.example.com'] },
|
||||
},
|
||||
};
|
||||
|
||||
expect(helpers.sanitizeSettingsUpdate(payload)).toEqual({
|
||||
gitProviders: {
|
||||
github: { apiBaseUrl: 'https://github.example.com/api/v3', detectUrls: ['github.example.com'] },
|
||||
gitlab: { apiBaseUrl: 'https://gitlab.example.com' },
|
||||
gitea: { detectUrls: ['gitea.example.com'] },
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('drops malformed gitProviders payloads entirely', () => {
|
||||
const helpers = createTestHelpersWithRealSanitizers();
|
||||
|
||||
expect(helpers.sanitizeSettingsUpdate({ gitProviders: 'not-an-object' })).toEqual({});
|
||||
expect(helpers.sanitizeSettingsUpdate({ gitProviders: [] })).toEqual({});
|
||||
expect(helpers.sanitizeSettingsUpdate({ gitProviders: null })).toEqual({});
|
||||
expect(helpers.sanitizeSettingsUpdate({ gitProviders: { unknown: { apiBaseUrl: 'https://x.example.com' } } })).toEqual({});
|
||||
expect(helpers.sanitizeSettingsUpdate({ gitProviders: { github: { apiBaseUrl: ' ' } } })).toEqual({});
|
||||
expect(helpers.sanitizeSettingsUpdate({ gitProviders: { github: { detectUrls: 'github.example.com' } } })).toEqual({});
|
||||
});
|
||||
|
||||
it('normalizes gitProviders apiBaseUrl scheme and strips trailing slashes', () => {
|
||||
const helpers = createTestHelpersWithRealSanitizers();
|
||||
|
||||
expect(helpers.sanitizeSettingsUpdate({
|
||||
gitProviders: { github: { apiBaseUrl: 'github.example.com/api/v3/' } },
|
||||
})).toEqual({
|
||||
gitProviders: { github: { apiBaseUrl: 'https://github.example.com/api/v3' } },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('session retention settings persistence', () => {
|
||||
|
||||
Reference in New Issue
Block a user